IENP{0::םLF56>lL3Sܱ}dH6.:$_aZ_ZmBH4C3Z29lÉܫOs&bQ&\d9dOLcs$áK2 C f!ˀݖ^.gIv[K߆(L`$E10#;8#Z8[. TȐ%b_s0,=nk,ˠ `%JyV)cP ۶. f֠ <%(*;'kl NJMbin/0000755000175200017520000000000013557057144012057 5ustar bushnellbushnellbin/makeExif0000755000175200017520000037432413557057144013553 0ustar bushnellbushnellELF(54\4 (# plll444444mmppp@\qqqhhPPP Qtd/lib/ld-linux-armhf.so.3GNUy*=?g;-9 "SvwH_i.k3m8nzqUrZKaxNtJY 7&^~puA|f!B4$']2o5TFM{W[6/IR` C %#@)1L , (E<ODPe+>hlXs0\Vdb:}cjGQ <" B Pp !>  e q! @uk ` <" g1  Dp !1 |<"  hp ! P & q! \vI <" m 8p ! p!   p!  |<" ) @u,4 u<  \v  f ab"  \vKC" f >  "m `  hq!R L" 1 \p !- Bpu,>V p!;  @uI v \v VCY   @u"  _r p!  8q!Li  Q+iG= n  R *v ue q! t&A  wz D" ,Glibpthread.so.0_ITM_deregisterTMCloneTable_Jv_RegisterClasses_ITM_registerTMCloneTablelibm.so.6__gmon_start__librt.so.1libudev.so.1libcrypto.so.1.0.0_fini_initlibasound.so.2libfdk-aac.so.1libopencv_core.so.3.1libopencv_highgui.so.3.1libvencoder.solibMemAdapter.solibVE.solibmp4v2.so.2libienso.solibstdc++.so.6_ZNKSt5ctypeIcE8do_widenEc_ZdlPv_ZNKSt9type_infoeqERKS__ZNSsC1EPKcjRKSaIcE_ZNSs4_Rep10_M_destroyERKSaIcE_ZSt16__ostream_insertIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_PKS3_i_ZNSt9basic_iosIcSt11char_traitsIcEE5clearESt12_Ios_Iostate_ZSt4cout_ZNSs4_Rep9_S_createEjjRKSaIcE_ZNSs4_Rep20_S_empty_rep_storageE_ZNSs7reserveEj_ZNSs6appendEPKcj_ZNSs6appendERKSs_ZNSs6insertEjPKcj__cxa_end_cleanup__gxx_personality_v0_ZNSsC1EPKcRKSaIcE_ZNSt13runtime_errorC1ERKSs_ZNSt9exceptionD2Ev_ZNSs6assignERKSs__cxa_allocate_exception__cxa_throw__cxa_free_exception_Znwj_ZSt18_Rb_tree_incrementPKSt18_Rb_tree_node_base_ZSt25__throw_bad_function_callv_ZNSsC1ERKSs_ZSt29_Rb_tree_insert_and_rebalancebPSt18_Rb_tree_node_baseS0_RS___cxa_begin_catch__cxa_rethrow__cxa_end_catch_ZNSs12_S_constructIPcEES0_T_S1_RKSaIcESt20forward_iterator_tag_ZSt19__throw_logic_errorPKc_ZNSs12_M_leak_hardEv_ZNSt8ios_baseC2Ev_ZNSt9basic_iosIcSt11char_traitsIcEE4initEPSt15basic_streambufIcS1_E_ZNSt6localeC1Ev_ZNSolsEi_ZNSs4swapERSs_ZNSt6localeD1Ev_ZNSt8ios_baseD2Ev_ZNSs6appendEjc_ZNKSt5ctypeIcE13_M_widen_initEv_ZSt16__throw_bad_castv_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEED1Ev_ZNSdD2Ev_ZTVSt9basic_iosIcSt11char_traitsIcEE_ZTTSt18basic_stringstreamIcSt11char_traitsIcESaIcEE_ZTVSt18basic_stringstreamIcSt11char_traitsIcESaIcEE_ZTVSt15basic_streambufIcSt11char_traitsIcEE_ZTVSt15basic_stringbufIcSt11char_traitsIcESaIcEE_ZNSs6insertEjPKc_ZNSs6appendEPKc_ZSt18_Rb_tree_decrementPSt18_Rb_tree_node_base_ZNSt8ios_base4InitD1Ev_ZNSt8ios_base4InitC1Ev_ZNKSs7compareERKSs_ZSt18_Rb_tree_incrementPSt18_Rb_tree_node_base_ZSt20__throw_length_errorPKc__errno_location_ZSt17__throw_bad_allocv_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6__ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc_ZNKSt13runtime_error4whatEv_ZNSt13runtime_errorD1Ev_ZTVN10__cxxabiv117__class_type_infoE_ZTVN10__cxxabiv120__si_class_type_infoE_ZTISt9exception__cxa_pure_virtual__pthread_key_createnSysLogEnfsynclibgcc_s.so.1__aeabi_unwind_cpp_pr0__aeabi_unwind_cpp_pr1libc.so.6fflushstrcpyclosedirftellputsabortstrtoll__assert_failrewindstrtodsyslogstrlenmemsetlocaleconvfseekmemcmpvsnprintfstdoutmemcpyfclosemallocopendir__xstat64__ctype_b_locstrtoullfilenofwritefreadmemmovefopen64__libc_start_maindirfdfree_ZNSt6vectorIcSaIcEE14_M_fill_insertEN9__gnu_cxx17__normal_iteratorIPcS1_EEjRKc_edata__bss_start__bss_start____bss_end____end___end_ZN8nlohmann6detail11parse_errorD1Ev_ZTIN8nlohmann6detail10type_errorE_ZTVN8nlohmann6detail12out_of_rangeE_ZN8nlohmann6detail11other_errorD1Ev_ZTIN8nlohmann6detail16invalid_iteratorE_ZN8nlohmann6detail16invalid_iteratorD1Ev_ZTIN8nlohmann6detail11other_errorE_ZTVN8nlohmann6detail10type_errorE_ZN8nlohmann6detail10type_errorD1Ev_ZTIN8nlohmann6detail11parse_errorE_ZTVN8nlohmann6detail16invalid_iteratorE_ZTVN8nlohmann6detail11parse_errorE_ZN8nlohmann6detail12out_of_rangeD1Ev_ZTVN8nlohmann6detail20input_buffer_adapterE_ZTIN8nlohmann6detail12out_of_rangeE_ZTISt19_Sp_make_shared_tag_ZTVN8nlohmann6detail9exceptionE_ZTVN8nlohmann6detail11other_errorE_ZTVSt23_Sp_counted_ptr_inplaceIN8nlohmann6detail20input_buffer_adapterESaIS2_ELN9__gnu_cxx12_Lock_policyE2EEGCC_3.5GLIBC_2.4GLIBCXX_3.4.9GLIBCXX_3.4.11CXXABI_1.3GLIBCXX_3.4.14GLIBCXX_3.4  D  U&y %  ii - ii -<)7aEӯkTd_t)ntt tt+t3tEtVtgtqtstt@u1puWussss s$s (s ,s0s4s8sFL(8(@-B/00.>94((@-B/00S>0+''@-B/00w>0x''@-H*00>0@'\'@-&00> 0'$'O-P㐷@- ]M B_ T0 80`< 00 PT@   0PL0@0 10"= 1S  3/P r 0@0W% 7."D 70Sc \:S    H&HƟ  4 ,&( H ,0 $S S00 R 0 0S <6 %0SH6\0D 0 @T \p,0 `  X 1 !PiP` @@T00V  @ T 1 !P dP0@p0$0S0S` (0S0Sr 40S0St $W 0S `3:S`!`0`fFb4tw x05Pb WW0G  @GS00T@@TW WX`VW00'0S'!zzgz: S1@  0T9p'00CS'08@3T0 @P]ߍ00 S 0 0R 08   W  695w\ @ PS q0S S&000 S S  R S B:S 0SZ@V@|00qO'C|0@T0   0S 1 @\ l3 `TC 1\ @ P 1`$     01 00!w `0 P`  h`@ O  h0 C P 0 0x0aAzDJL0K,,++`*\'\''@(''''('&P&x $P $l& @T @ P PD B50$0D *50(0D "5040xH}3 @ @ P O@r0SM 8< 9@P@>3 I@O @XT `&#6tt00.p,p@'lDlp ؀# /->@@vd` @ m "d0 C P#3 E``<@ P <#`0 C Px#|3 x3` @ P 33d @ P 0q043\ @ P L @ P 44\4.`0d>=0x4.|0>=00@1@S  3/P r44h @ P T$505  --- 0%<@(;0 0 R/ =00`S/0S//@uCu(0$`AQ/0S//@u@u@-@0S00u@- 0S 0S 3/@p`0` 0-0S 0_/B^R_:0 0C0R4<8@-PPL@@ @0 @d8 0@0 ;0-I-PMM 00 @P P p  KsX` 0  Y0XV 0KIЍ/ $00 0  <; /p @-Rlh O-PpWMM` PTJ@ rWލЍ0,O_ ! <0 ΋ύ )O  ~ *1HbPL2ύ mT @>8b<2o [ 00 ,2 ("ύ~O I  020 2΋.j /}΋zo Tp-͋vO $c΋ro V΋3nO  I΋` <.͋fO d/΋b 4"͍^O  9됑0a΋1Z ΋VO /͋R d΋=NO 4>΋J ΋FO  ˋ BA ΋B@ hC΋Cp 0 @  @E 0`0E΍ F q1͋Gp p d΋@I< U΋IpJ F΋J @K 72͋xp M*΋Mh@Nd ΋NXpO,  O΍H@    X`0`Q΍\08p  RH`0P΋L0R@`(S` 3S~p;p  ͍ U qppW 0S    P  i  R 0@W>T81IWN`T 4 @P I@^0`0 @P @DtbD:<<P ''h4lH$|X,P h@h 332/0P/00/// 0 0/0 S 2 55#/@-@@-@$0$ 0@-@P .@-M @ n bR !0aЍC-0r$M,2 Pp`@  00%    1P  0  0  \\# P` 0 % 0 0 0 @P @P @P0 CP$ЍO$Ѝ  @P  @P   @P  @P x @P  @P .   ( O-< h4@-Q@ Q Q0S 0SH DD000S$   00\`,O- MP UP( p P` @ T1 ! qP dP 0 0SR aPkP000P0 Ѝ 0SP00 0P`p @  T 1 !0@-SQM@PЍs0`S=840,765%@@ ,!0 n1@ . $ p 00 0 CP0 CP 0  @P  @P Cx0pXD0(O- MP UP( p P` @ T1 ! P dP 0 0SR PkP000P0 Ѝ 0SP00 0P`p @  T 1 !O-pR,M`(P@"0 p0Z0 00pA 0 p P 0W1! [0P0 g 0R OPePW0 @Pj ,Ѝ 0Si 0 0 pW 1 !10PeP R00S 0 06P0D N $0S co[[6 P p0W 1 !0Pg  0000,Ѝ0S R0 0 Y 1 !0PiP R000O-@P,MUC UT 0 0 a@T' ` p  P U 1 !PkPp @@TZ  @ T 1 !P dP d2 Fp0P5,Ѝ p@"(0   #.  `p 000 PPP  0P U 0`SA <840;:9)$p 0 @X!0 41(P 1 % @ 00$ @P 0 CP 0 !DAl0 0 @P 8$ @P 1 @P $+n 0@(p@-@uP| 0R000 0003/00@ S=A0@SXa0@SdW@V 0S; 0 00@ ^+A0@SGa0@SPW @d 0S- 0 00P@ UA0@S6a0@S<W@ R 0S 0 000@ SpVdRA0@S7@p003/003/003/7@V70@d7@Ra0@SW@pp 0&0> 0뤽XO- M@ kN2 S20c nP   0 Zh 0 `pP" PP] AS`P# P% PPQ   R0 S Q@CQ@CPP6P( $$10PPP@ Q Q0S"  [@ TQ0S0SP ^0P Ѝ   P@ <<00KroR t DP0O-0C0S$MPS00$Ѝ@0`Srm`bdlkjc00{{z @ 3"0 l2 @ X 00   .!  p 00 @PK @PD1.!0 00 0 CP/1 GP000% @P 0 CP|!x1 -ld\TLDPMJ GDA @P : @P 4 @P . @P (k @P  GP 0@@<84(0O-0C0S$MPS00$Ѝ@0`Srm`bdlkjc00 {z @ S"0 l2 @ X 00@  .!< )p 00 @PK @PD1.!0 00! 0 CP/1 GP000% @P 0 CP|!x1 Mld\TLDpmj gda @P Z @P T @P N @P H @P ?! GP 80@0d0O-0CPC$MP`@S*,$Ѝ&0`Sxgikmrqpl0:gzz , {z P k"0 l2 P X 00X  .!T Ap 00 @PK @PD1.!0 009 0 CP/1 GP000% @P 0 CP|!x1 eld\TLD |y @P r @P l @P f @P ` @P W9 GP P0P` 0O-SC$M@ S S PF0`Ssbdfhmlkg00$Ѝ{{z P "0 9l2 P X 00}  .!y fp 00 @PK @PD1.!0 00^ 0 CP/1 GP000% @P 0 CP|!x1 ld\TLD  @P  @P  @P  @P  @P |^ GP u0PXxR/G-@ p` lT PaT * Pd \ 0K U008 Gw@T:U1@U@ Gh b TB\ 0\Pb- UPW- PR@# @P l@ b^ Z  6 O0XPb  C  ? 0@-@$0P M  `Q ` S* $ P Ѝ0 ` R015 l0d$0 `O-Mp`WRppn@P$ 0 0lRP  lP_*a0V$050 S$0  `Q!  `SG*P V$ ! 0 S   0 S00(0Ѝ003/ `\ 0 15pЍ b 0 $0 `0p lS0 15 b0 $ lL 0"R CO-@$P1p460(0<ЍPPzPPv0 003/P P80 06P 0P`(00000x50(0<Ѝ\P PM 0R000 0F \$00C$0<Ѝ 0(0 0R00 0 00K?S$0  `Q|  `S* $ 003/0K?S@40(0<Ѝ0040(0u003/"@SP񏐜~}|{zyxwvutsrqponmlkjihgfedcbt`_^]\KZYXCVUTSRQP7NMLGJ-  `\F 0 15y p] 6;@ SA:7;@ S\:Py*PC PM[CK [?      /" t10(0 b0z $0 `-\P 010(0K[@00(000(0uPp 7;@ S* ׷KK0&|0x>0d0_'`0\>0|8`Dԡ@Ȳ 0A-0C$ - A0M@ Rzexw.Pv` 0R00~  `9Q0Qu.Q&Hd 0R00c 0 000A S50(0Ѝ0PO 0R00 0 0EP eP .P $0  `\A  ` S?* `$ U`$00C$0 U l Ѝ- 0R00 0 00Q 9QP 4.0>E003/003/z003/9Q|EQ eQ 0R00k 0 0+0ASK7I5GFPp` P00H S$0  cQ5c\* $ 0R00003/00H SP[ 0R00 0 000A S20(0h20(0c003/7 PcRu015q003/Pf 0R00*  PEQw C00A SV10(0/PMp`' `$0`p 0RK0Sc003/p`' `9$0`p 0R60SceQ0 u ` R015003/p `00$cF l0}$0 `\0)XX0>*D0*@@0>!Hз484ȫ8@-@P 0R00  P P P @00R0S~Pd]^[ZYXWVUTSRT*Pm003/m 888@ 88@ 8 0R00r 0 0aP 0R00 0 0lPz 0R00 0 0sPo 0R00 0 0ePd8 0R00P 0 0uPW 0R00b 0 0lPL 0R00c 0 0lPA8 0R00' 0 0rP4 0R003 0 0uP) 0R00F 0 0eP8(10(08003/003/003/ 88 800(08003/003/q003/003/p003/003/003/ihh0O-S,TM@ 7`PQ 00 0B S񏐜9}yIMQ_rV 0S  0P @0$p U P 0S  A0P 00 0 0V 0S  0 S  00 @0$ 000 P @ @ h[ tfp P`_ L0P@00 0 0i 0$0tLt, 0S  @0$ M 0HS  0V 0S  0AP00_C PV 0S  0AP00 C$0 @P#  9 zP 4t+0:=0\ " $0 @P mG5@0 @P (`P l% p5P  00@ 000P  (  @ @P $00 @P (0 @P $&(6 o@0 @P $00 C0P @(0 C0P @600 @0 @P }O-P@MgpT` 70S 0_/ Q_0  S   3/0 S0 ,  $p  3/ 00 ,0T040 60S 0_/ Q_8<@_/ Q_ 0@0 D H L P T X P+X +RL6X0 T`0\ YP 0S.00T0 50S~ 0_/BPR_3 800 p074 p 0ST SV S0S %4P0S0S PP *003/_ ?CP_?003/_ ?CP_B003/_ ?CP_H,0S  3/0S  3/l8T8p@-(x`MPb`@iЍp} 00P0 @P _G-@8MP 0 0 !Q0  PU `p('@b/0 p 0pQ@`  P`U Ѝ2 eP0P0 @P #i@ꌵC-@0P`0 @R9 R R R*  CReB<5  RL HH207P@0@S S S0S 10 R0S 0S   00P 0 @  @d D4@@ PT U @PWP0Pq 0 @ 00Q0   0S  0S00y PhlY {P x~Lh~R/O- p0LM@ cBXQ//@0jC2 cX#S  0rSj2J00 ` PU `VPPT 0 0^ ^Q  `LSQ Q QQ  T0 S \C\C^Q P0d0C2X?*200cS-  `p \ \\ @Q`\ \ \\  U Q P؀APA\\ dQ  =a`p*P P0S 00A0`S S S R  X0H XH"\ H \ \0S~ H U QPA AQ"P0S}0T@(P LЍ\< \900S[ 00D4S T0( DP oX@  =(\00SS 00D4S T0( DGQ&8 4450Q'Q#400S 00D4S T0( D T7 `p^# ^0S A0P`S! S S0S @Z P Q @Q @^0S0S0S0S U PZZ 200LЍ\\\0S0S1{0S- Rs RXs p`V  pW`0T200_ `@pT X pH 0 @ U 8@\) \f@0Sm @0FDS V08 Fb U`  O8\@0Se @0FDS V08 FY@0S @0FDS V08 FjRJ$ 0  07U PFTD#(D D @&T @5/ +VF$8F Fx tt00O@0S C@BZ Y먊0w`,s@-@P$Mr`Up# U,0cL  V*$Ѝ P0 0e l0sQ3 Q& Q0Sn w00$Ѝ0 0PPPPU 0`SLGC?;FED40S 100Sx @ d!0 P1 P 1 % @ 000 CP 0 CP!1 #FC 00h0@ @P 2u @P (K뀧 tq؇00Lp,0, 0@-@000mx404 0@-@000^N<,0, 0@-@000M404 0@-@000>.輣,0, 0@-@000-x404 0@-@000<,0, 0@-@000 404 0@-@000z輢,0, 0@-@000ix404 0@-@000Z<,0, 0@-@000I404 0@-@000:輡O-@PTM 0p 0Pv(20P0Ua/S[ 0Pf0U?0s0/SS  ` 0s0S Y AP: 0PEU0?0 ` 0s0S?  0sP2U0?00 S  0dX#  P0  P P TЍ?0s00S n 0@0TЍTЍTЍ? c/oQ" R `F`FP@-0@S. Qv 1Q 1Q 1Qs 1Q 1Q 1Q GQ 2Q 2Q 1Q 1Q JQ 1Q 1Q 1Q 2Q 2Q -1Q >1Q ?1Q 2Q Q 21Q 1Q 1Q Q 11Q ;1Q 2Q i7Q %8Q 0 Q F7Q Q Q 0 Q 1 Q 1 Q 0 Q 0 Q |2 Q 2 Q 0 Q 0 Q 0 Q 2 Q 2 Q 2 Q| 2Qv 2Qp "8Qj $8Qd '8Q^ (8QX 08QR 18QL 28QF 38Q@ 48Q: 58Q4 2 Q. 2 Q( 2 Q" 2 Q 2 Q 2 Q 2 Q  2 Q 2 Q 2 Q 2 Q 2 Q 2 Q 2 Q 2 Q 2 Q 2 Q 2 Q 2 Q Q 3 Q 3 Q 4 Q 4 Q 4 Q 4 Q 4 Q 4 Q 4 Q 4 Q 4 Q{ 4 Qu 4 Qo 4 Qi 4 Qc 04 Q] 14 QW 24 QQ 34 QK 44 QE 54 Q? Q: KP PN QY Qo Q[ Qq Qu Qy Q} Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q {xphdoXPH@80( xph`XPHy@v80(m j}a^tqnkheb_\Y=:741.x+p(h%`"XPH@8,0(  xph`XPH@80( }zwtqnxkphhe`bX_P\HY@Vԇx̛Txxhx(<<(xЀ,x܀$x؀xԀxȀxxwwwwwwwwxwwtww,d xxwwwwpwTw4ww lH$ w؃dH$̂|X8́dH ؀hT< lL,~~~~p~P~4~ ~~}}}drDrt}\}D}(}-A-M M`:P$0 :(00V @pT p 0pڍ ЍA Ѝ/}p# \~P/0O-SM S) S- S. S& $ $ P400S  @T l4ph00`4 00T40 00S ` , 00p |1S00C S񏐸m\H7$0Sڜ` 0 !` 0[0Sʛ0STc`0 !K0 Sʋ0Sc`0 !r :0 Sz0Swb`0 !*0 Sj0Sgڜ` 0 !` 00SW0STTb`0 !0 SG0SDb`0 !r 0 S60S3a`0 !0 S&0S1#[ jp`p 0 0` ^  Vp0[ *4$ @Tߍ`0S   1S&     x  ~~}~`@~0~}}}}}||D|{{d{zzT{y zzyypyly-@-M M:0 @0Isڍ Ѝ@ Ѝ/xP/0O-SM S# S' S( S  $ $ p40P  t @T X4`T0P0L4 0 00S Pb 00 ` 1S00C S񏐵m\H7$0SڌP 0 !P 0z0U0SDSP0 !j0Z0SSP0 !r Y0Zw0StRP0 !I0Zg0SdڌP 0 !P 060UT0SQDRP0 !&0ZD0SARP0 !r 0Z30S0QP0 !0Z#0S1#Z P 0 0P \  U0Z *0  @T ߍP0S   1S)     x  Hz0xDxԋ(xHxhx`xwwwwDw wvtvvuu$utus\tussss|?O-M0MP@0  0PND 0WPG I / 8P0`?o2S1T?s01D n0pS& aTPuP 0     0`0 PV_ >00x>00p>0 0h>0$0  P D 0 P0I)8`0b?o2S0 T0 T3?/1 DD0 #TQQ  6`V V=08V:PTX$ 0     P` R 1T S0S ݍЍ 0S 1T SQ Q0̟0 qW:pTX 0 0 PPSP`PPPPp001 R` 0S` U QQA  AA\o^ 00ASo  0SXRd -   paXpT 0 V P   0p`1   D RP 0SP :  00 0P `pTXPTo g0     pP` RK 0SVT* 1T   !P ݍЍ  p ZP(P:PTX< 02 0P0 R 0SPP  \9  00 0^P U R  0`P:TX0T% 0 0 Vp00`1    Rp 0Sp U 0  PP0 $8 0 0 0PC  0xW :0S ھ8I)0b?o2V p0 2/ STX0Tp 0  0W`0p S Sp! ~W u  p30TX% @P T@0SPP P @U PRP PTP 0XpTK C 0 `S00p1 0P R`/ 0S` (00P 00   \2W W PTX( 0  0pP0Q QPPaU   Rp 0Sp 34  00 0.PP,  0\$0SEW W `B<  @0` P 0 U  0@TpTX`TP 0     p`P R 0S  0S  0M`P:TX0T P 0 IQT( l/o"V_uPP#SYTS T S  TS T MD 0"P"I  80`?o2U1  XC  R@ \ 0QE 0S3(IT l/o"V4 T /pr   IyPP B < (,$  P8!T0g?o2V"44s 0 00 S0 0( 0,N T 0@T 2\ 0S  R0PU P 0 0 )@PE 0 P AADtk(kȅ܄<~8{(zy w p< BPp  (I9 c/o"PV1X0011?TX`T 0}0 pPSPPPP00`1{ m0@Tyc00/u@-pPU` @P T@0SPP P @UPU@P/9Q00@-@PPP@-@P> P; `PP5 P0S/ @T+@T( 0S`V" 0P00!0`!pW S SAA  @T   P/P/0S0S/P//P/@-@P  P @P/0S0S QP P 0S////A \p@-@MS001 ЍpRS+ 00ЍpP`P& 0QQP  QQ 0AS0AS Q Q T00ЍpЍpZT 00P LP/O- MPU 0P PRU00`p<0S0@:0 R @T Ѝ P l jX RP ^ P ZXZ00000  d PE!U @@PG-H PUG 0@@\0Q00Q- 0S`pPP3 0  䰀P崀ẀἀPP(  GT I  W00R 00V @@W 0 0W 00P/@-`V/`V, 0Q@PpT@T 0S pR 000S P P @0T0C000RPZ G-@TG@TD 0Q0PS0S Q 㲠` 80XpPᲠ# V$ Z ZQ#X @0S Rp 0Sp 000 01Y   /QPC- 0SR0S \pW 0S  P P 0SR 00 00谑Y0X `@PP  TT 00QP R A-`V:`V7 0SpP @T  Ra P0 S$ PU0P     zp@T  0SP R 0SSC0CPS00S8 2R@ "0S; @TN0P @@@@@ ?@ RN 0SP )0SSC  0CQ  S00SPP0 0 0 p1 0SSC  0CQ  S00S P  P 0 0 01/PP@ A-@MM`Ph  0PDژpP]  XPA 0XM 0X1@U D 0wP:1T00SDqA P +P*0^PP0 ڍЍPP@0 CP 0pUTTTLLh0d 0p@- O`IYH00 V  (*@XIp4KSep@-M a@0P`0$0 =P 0 Ѝp P Ѝp@0 @PQ8?8| I M 8S S0`?o2S9 ?9s0*S 2/,00 *S Jddd\dC-@MM`Pf P?ڜpP_ QP Y @;lQ P0 PI:0 P&: PT 1 0 P3 PP*0|@P0 ڍЍ @PY P0 ]@ 0Q QQLc(c`cC-MP p  @HPP[ %PY(400S 400SX4I)08S^ # c `PF  R iP 00S \Q0Qg`%8P: %0S5  R QNX``a# p0S  G00SpU Ѝ0S n" 1S0Q  IP 01`@200S 00O Q8  1P- 01` 'P6 0S  R R 0S` R!R0Q  P8 `H100S00`a p!0Sy100S` `0 `QP 1S`>04000S` p`l$Oa 0PlPU $I PU 1S(0 h/o"Vn ?D4D03DAP Q񏐃L@+"G;& R@ R@@ RA R R   R  Q @@@U !W  SZ    R' `V$ \   Q  R"\ `V Q RRB BPR  R W X㰁SQPl 0SSC0CQS00S0P PR6cSu PAPP@@@\PQ@8 @S@T  QQ @T@ZT 0%S @T 0S0SSC0CPS00S0Sg Q) @QQ@AAT@QQ@ @@Q @ \*  R% `V0ٿ ````` ɿ` 0R P   ARRB BQp@R@lQQ  @ @T i`\)Q& `VZR %\WQQAA\QQ7Q @1QQAA^QQJ ZhLZXEW::assert_invariant() const [with ObjectType = std::map; ArrayType = std::vector; StringType = std::basic_string; BooleanType = bool; NumberIntegerType = long long int; NumberUnsignedType = long long unsigned int; NumberFloatType = double; AllocatorType = std::allocator; JSONSerializer = nlohmann::adl_serializer]nlohmann::detail::lexer::token_type nlohmann::detail::lexer::scan_literal(const char*, std::size_t, nlohmann::detail::lexer::token_type) [with BasicJsonType = nlohmann::basic_json<>; std::size_t = unsigned int]static T* nlohmann::basic_json::create(Args&& ...) [with T = std::basic_string; Args = {const std::basic_string, std::allocator >&}; ObjectType = std::map; ArrayType = std::vector; StringType = std::basic_string; BooleanType = bool; NumberIntegerType = long long int; NumberUnsignedType = long long unsigned int; NumberFloatType = double; AllocatorType = std::allocator; JSONSerializer = nlohmann::adl_serializer]static T* nlohmann::basic_json::create(Args&& ...) [with T = std::vector, std::allocator > >; Args = {}; ObjectType = std::map; ArrayType = std::vector; StringType = std::basic_string; BooleanType = bool; NumberIntegerType = long long int; NumberUnsignedType = long long unsigned int; NumberFloatType = double; AllocatorType = std::allocator; JSONSerializer = nlohmann::adl_serializer]static T* nlohmann::basic_json::create(Args&& ...) [with T = std::map, nlohmann::basic_json<>, std::less >, std::allocator, nlohmann::basic_json<> > > >; Args = {}; ObjectType = std::map; ArrayType = std::vector; StringType = std::basic_string; BooleanType = bool; NumberIntegerType = long long int; NumberUnsignedType = long long unsigned int; NumberFloatType = double; AllocatorType = std::allocator; JSONSerializer = nlohmann::adl_serializer]void nlohmann::detail::lexer::add(int) [with BasicJsonType = nlohmann::basic_json<>]bool nlohmann::detail::lexer::next_byte_in_range(std::initializer_list) [with BasicJsonType = nlohmann::basic_json<>]      int nlohmann::detail::lexer::get_codepoint() [with BasicJsonType = nlohmann::basic_json<>]nlohmann::detail::lexer::token_type nlohmann::detail::lexer::scan_string() [with BasicJsonType = nlohmann::basic_json<>]nlohmann::detail::lexer::token_type nlohmann::detail::lexer::scan_number() [with BasicJsonType = nlohmann::basic_json<>]void nlohmann::detail::parser::parse_internal(bool, BasicJsonType&) [with BasicJsonType = nlohmann::basic_json<>]static char nlohmann::detail::lexer::get_decimal_point() [with BasicJsonType = nlohmann::basic_json<>]nlohmann::detail::iter_impl::reference nlohmann::detail::iter_impl::operator*() const [with BasicJsonType = nlohmann::basic_json<>; nlohmann::detail::iter_impl::reference = nlohmann::basic_json<>&]m_type != value_t::object or m_value.object != nullptrjson.hppcurrent == literal_text[0]object != nullptryylen < yytext.size()ranges.size() == 2 or ranges.size() == 4 or ranges.size() == 6[json.exception..%d] parse_errorparse error%u at : invalid_iteratortype_errorout_of_rangeother_errornullobjectarraystringbooleandiscardednumbertype must be string, but is m_type != value_t::array or m_value.array != nullptrm_type != value_t::string or m_value.string != nullptr961c151d2e87f2686a955a9be24d316f1362bf21 2.1.1basic_string::_S_construct null not validtrue literalfalse literalnull literalstring literalnumber literal'[''{'']''}'':'','end of input'[', '{', or a literalunknown tokensyntax error - ; last read: 'unexpected ; expected ImageWidthImageHeightDateTimeOriginalDateTimeDigitizedGPSVersionIDGPSLatitudeRefGPSLatitudeGPSLongitudeRefGPSLongitudeGPSAltitudeRefGPSAltitudeGPSTimeStampGPSSatellitesGPSStatusGPSMeasureModeGPSDOPGPSSpeedRefGPSSpeedGPSTrackRefGPSTrackGPSImgDirectionRefGPSImgDirectionGPSMapDatumGPSDestLatitudeRefGPSDestLatitudeGPSDestLongitudeRefGPSDestLongitudeGPSBearingRefGPSBearingGPSDestDistanceRefGPSDestDistanceGPSProcessingMethodGPSAreaInformationGPSDateStampGPSDifferentialGPSHPositioningErrorcannot use operator[] with current == 'u'type must be number, but is vector::_M_fill_insertinvalid string: ill-formed UTF-8 bytecurrent == '\"'invalid string: missing closing quoteinvalid string: '\u' must be followed by 4 hex digits0x00 <= codepoint and codepoint <= 0x10FFFFinvalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFFinvalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFFinvalid string: forbidden character after backslashinvalid string: control character must be escapedfalseinvalid number; expected digit after '-'invalid number; expected digit after '.'invalid number; expected '+', '-', or digit after exponentinvalid number; expected digit after exponent signendptr == yytext.data() + yyleninvalid literalnot errorednumber overflow parsing 'loc != nullptrArgument Error argv [1] = inputFile, [2] = outputFile, [3] = json input test.jpg test_result.jpg '{"TagName":{"ifdType":1, "tagId":271, "tagType":2, "value":"IENSO"}, "GPSLatitude":[14,23,123.11] , "GPSLatitudeRef":"N" , "GPSVersionID":[1,2,3,4] , "DateTimeOriginal":"2011:11:31 12:00:01"}'input file path Errorm_it.object_iterator != m_object->m_value.object->end()m_it.array_iterator != m_object->m_value.array->end()cannot get valuecannot use key() for non-object iteratorsifdTypetagIdtagTypevalue] doesn't support, you should use manual tag insert{"TagName":{"ifdType":1, "tagId":271, "tagType":2, "value":"IENSO"}createTagInfo: ret=%d Create Tag ErrorupdateExifSegmentInJPEGFile : ret json parse ErrorError TAG [ExifupdateExifSegmentInJPEGFileImageLengthBitsPerSampleCompressionPhotometricInterpretationOrientationSamplesPerPixelPlanarConfigurationYCbCrSubSamplingYCbCrPositioningXResolutionYResolutionResolutionUnitStripOffsetsRowsPerStripStripByteCountsJPEGInterchangeFormatJPEGInterchangeFormatLengthTransferFunctionWhitePointPrimaryChromaticitiesYCbCrCoefficientsReferenceBlackWhiteDateTimeImageDescriptionSoftwareArtistCopyrightExifIFDPointerGPSInfoIFDPointerInteroperabilityIFDPointerRatingExifVersionFlashPixVersionColorSpaceComponentsConfigurationCompressedBitsPerPixelPixelXDimensionPixelYDimensionMakerNoteUserCommentRelatedSoundFileSubSecTimeSubSecTimeOriginalSubSecTimeDigitizedExposureTimeFNumberExposureProgramSpectralSensitivityPhotographicSensitivityOECFSensitivityTypeStandardOutputSensitivityRecommendedExposureIndexISOSpeedISOSpeedLatitudeyyyISOSpeedLatitudezzzShutterSpeedValueApertureValueBrightnessValueExposureBiasValueMaxApertureValueSubjectDistanceMeteringModeLightSourceFlashFocalLengthSubjectAreaFlashEnergySpatialFrequencyResponseFocalPlaneXResolutionFocalPlaneYResolutionFocalPlaneResolutionUnitSubjectLocationExposureIndexSensingMethodFileSourceSceneTypeCFAPatternCustomRenderedExposureModeWhiteBalanceDigitalZoomRatioFocalLengthIn35mmFormatSceneCaptureTypeGainControlContrastSaturationSharpnessDeviceSettingDescriptionSubjectDistanceRangeImageUniqueIDCameraOwnerNameBodySerialNumberLensSpecificationLensMakeLensModelLensSerialNumber(unknown)GammaInteroperabilityIndexInteroperabilityVersion%s1ST0THEXIFGPSInteroperability {%s IFD} tags=%u tag[%02d] 0x%04X %s type=%u count=%u val= - %s: (error)%u [%s]%hu %u/%u %d %c 0x%02x (omitted)%hd %d/%d rbhttp://ns.adobe.com/xap/wbExiflittlebigsystem: %s-endian data: %s-endian critical error in %s IFD 0th1st[%-7s] %-10s : %sC APP[ERR ] %s:%d ==> Error in fwrite err=%d, writeLen=%d, readLen=%d, readLenTotal=%d and writeLenTotal=%d end of read/write BEFORE FSYNC end of read/write readLenTotal=%d and writeLenTotal=%d, fsync=%d there is no DCIM directorythere is no DCIM directory end of directory DCIM fsync=%d end of read/write BEFORE FSYNC /media/photos/DCIM/Eܲp'@$t|I8H\$4DP4DP̿4DP4DPth"48DX8L  0! 0Ⱦ?b8d    t            X[,\p (Ƚ '@0X000 <       < d8&# L  ػ!(D4TP}9, P$}hA8MC }ĺ"l?0  L 0$ @l((pd48X4h,4X|LTX` p ( d    @t8l #%h&L(h/h6<DG88O`OQS]T`65d68(Hu<xuD<pxux<uxu<,pxu<,pxu<,pxu=,pxu$=,pHuD=xup=tpHu=xu= p pt&Ct&,p|t8p8tDp|tPp8t\p|thp8ttpt&t&|p DDC,DpC@DCTDXD[t"0<D  L" <ppp z slxo4ooqX"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"X"Pp qDp|hpq8ppp|Chq\ppp8qqONNNNNGCC: (Buildroot 2016.11-g8d16ac1) 4.9.4A>aeabi4Cortex-A7 A  "*,D5T9P5T9../../../libgcc/config/arm/ieee754-df.S/home/bushnell/ienso/buildroot/output/BUSHNELL_IMPULSE/build/host-gcc-final-4.9.4/build/arm-buildroot-linux-gnueabihf/libgccGNU AS 2.26.1MT9;../../../libgcc/config/arm/ieee754-sf.S/home/bushnell/ienso/buildroot/output/BUSHNELL_IMPULSE/build/host-gcc-final-4.9.4/build/arm-buildroot-linux-gnueabihf/libgccGNU AS 2.26.1%%I> ../../../libgcc/config/armieee754-df.S5/361//00////2/0////////301////3/1///3/3/21///////////0//2/5//3///1///1//50////2/////.0//0/3///2////20/5/20//2////1/////2/////2//3/0///20/00/10//02//1///0//0//2/// .0//0//0/// .0/////2/60/////02/6///0///00/1////6000/3000/3/1/ ./1/0/0/0//////> ../../../libgcc/config/armieee754-sf.ST94/3 .0////2/0///0301//0///02/22//1/3/3///1//1/5/0//2////.///5//403/0///100/0/10/02/1//0//0//2// .0///0/// ./3000110/ .00/300/3/10//10/./2/0////0/0////0/4Pp4l L" X" & < <dlmppppqsu@u^Pa5 ^(l^5 ^<^u5 35 ^5 L" < @T" < C ^PlC ^XlC ^XlC ^XlC ^Xl D ^Xl,D ^Xl@D ^XlTD ^XlXD ^D ^XlD ^Xl& &0 ^& ^l& &4 ^' $' $'4 ^L' X' X'8 ^' ' z'8 ^' ' '8 ^' ( n(8 ^,( 6 6p ^(7 ^(l07 "07d ^7 7 h7 ^d8 ^dD ^G ^e^`l$G ^pK ^Pe^hlK ^XM ^e^pllM ^(O ^e^xl >@ATTC= E 8Hd H K KjV xK LT L ,Mv` M N N N N N O O^u^O^u uu)p5 65 ^6 (6 8(6 ^X6 ^ud6 Kd6 ^6 au^ppp6 6 ^6 ^pp^u| |t ^   ^   ^  t ^  d ^|  \ ^d  ) ^`  ^  ^  ^@ L <LD ^|  ^` t ^ H ^ ( <) ^[2[9$[^8u8uG5 C>d>`9 q>(;| }>D >>>U" @Z@XD4" @C" WA sAAAAHT A< AD" B B>Bp !BB$" 5C<" YCzC@ C C C=!!C,D" D$DuBDx8( NDo" D Eq!uE; E:( Et&E E u" ;F|p !hF5 vFFFFD" G7G/home/bushnell/ienso/buildroot/output/BUSHNELL_IMPULSE/build/glibc-2.23/build/csu/abi-note.o$d/home/bushnell/ienso/buildroot/output/BUSHNELL_IMPULSE/build/glibc-2.23/build/csu/start.o$a/home/bushnell/ienso/buildroot/output/BUSHNELL_IMPULSE/host/usr/arm-buildroot-linux-gnueabihf/sysroot/usr/lib/crti.ocall_weak_fn/home/bushnell/ienso/buildroot/output/BUSHNELL_IMPULSE/host/usr/arm-buildroot-linux-gnueabihf/sysroot/usr/lib/crtn.o_ZNK8nlohmann10basic_jsonISt3mapSt6vectorSsbxydSaNS_14adl_serializerEE16assert_invariantEv.part.26_ZN8nlohmann6detail5lexerINS_10basic_jsonISt3mapSt6vectorSsbxydSaNS_14adl_serializerEEEE12scan_literalEPKcjNS7_10token_typeE.part.89_ZN8nlohmann10basic_jsonISt3mapSt6vectorSsbxydSaNS_14adl_serializerEE6createISsIRKSsEEEPT_DpOT0_.part.103_ZN8nlohmann10basic_jsonISt3mapSt6vectorSsbxydSaNS_14adl_serializerEE6createIS2_IS4_SaIS4_EEIEEEPT_DpOT0_.part.165_ZN8nlohmann10basic_jsonISt3mapSt6vectorSsbxydSaNS_14adl_serializerEE6createIS1_ISsS4_St4lessISsESaISt4pairIKSsS4_EEEIEEEPT_DpOT0_.part.198_ZN8nlohmann6detail5lexerINS_10basic_jsonISt3mapSt6vectorSsbxydSaNS_14adl_serializerEEEE3addEi.part.234_ZN8nlohmann6detail5lexerINS_10basic_jsonISt3mapSt6vectorSsbxydSaNS_14adl_serializerEEEE18next_byte_in_rangeESt16initializer_listIiE.part.235_ZNSs4_Rep10_M_disposeERKSaIcE.part.9_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc.constprop.259_ZN9__gnu_cxx12__to_xstringISscEET_PFiPT0_jPKS2_St9__va_listEjS5_z.constprop.265_ZN8nlohmann10basic_jsonISt3mapSt6vectorSsbxydSaNS_14adl_serializerEEC2EDn.constprop.261_ZN8nlohmann6detail6parserINS_10basic_jsonISt3mapSt6vectorSsbxydSaNS_14adl_serializerEEEE6expectENS0_5lexerIS6_E10token_typeE.part.136_Z41__static_initialization_and_destruction_0ii.constprop.252_GLOBAL__sub_I_makeExif.cpp_GLOBAL__sub_D_makeExif.cpp_ZZNK8nlohmann10basic_jsonISt3mapSt6vectorSsbxydSaNS_14adl_serializerEE16assert_invariantEvE19__PRETTY_FUNCTION___ZZN8nlohmann6detail5lexerINS_10basic_jsonISt3mapSt6vectorSsbxydSaNS_14adl_serializerEEEE12scan_literalEPKcjNS7_10token_typeEE19__PRETTY_FUNCTION___ZZN8nlohmann10basic_jsonISt3mapSt6vectorSsbxydSaNS_14adl_serializerEE6createISsIRKSsEEEPT_DpOT0_E19__PRETTY_FUNCTION___ZZN8nlohmann10basic_jsonISt3mapSt6vectorSsbxydSaNS_14adl_serializerEE6createIS2_IS4_SaIS4_EEIEEEPT_DpOT0_E19__PRETTY_FUNCTION___ZZN8nlohmann10basic_jsonISt3mapSt6vectorSsbxydSaNS_14adl_serializerEE6createIS1_ISsS4_St4lessISsESaISt4pairIKSsS4_EEEIEEEPT_DpOT0_E19__PRETTY_FUNCTION___ZZN8nlohmann6detail5lexerINS_10basic_jsonISt3mapSt6vectorSsbxydSaNS_14adl_serializerEEEE3addEiE19__PRETTY_FUNCTION___ZZN8nlohmann6detail5lexerINS_10basic_jsonISt3mapSt6vectorSsbxydSaNS_14adl_serializerEEEE18next_byte_in_rangeESt16initializer_listIiEE19__PRETTY_FUNCTION___ZStL19piecewise_construct_ZZN8nlohmann6detail5lexerINS_10basic_jsonISt3mapSt6vectorSsbxydSaNS_14adl_serializerEEEE13get_codepointEvE19__PRETTY_FUNCTION___ZZN8nlohmann6detail5lexerINS_10basic_jsonISt3mapSt6vectorSsbxydSaNS_14adl_serializerEEEE11scan_stringEvE19__PRETTY_FUNCTION___ZZN8nlohmann6detail5lexerINS_10basic_jsonISt3mapSt6vectorSsbxydSaNS_14adl_serializerEEEE11scan_numberEvE19__PRETTY_FUNCTION___ZZN8nlohmann6detail6parserINS_10basic_jsonISt3mapSt6vectorSsbxydSaNS_14adl_serializerEEEE14parse_internalEbRS6_E19__PRETTY_FUNCTION___ZZN8nlohmann6detail5lexerINS_10basic_jsonISt3mapSt6vectorSsbxydSaNS_14adl_serializerEEEE17get_decimal_pointEvE19__PRETTY_FUNCTION___ZZNK8nlohmann6detail9iter_implINS_10basic_jsonISt3mapSt6vectorSsbxydSaNS_14adl_serializerEEEEdeEvE19__PRETTY_FUNCTION__._102._101._100._99._98._97._96_ZStL8__ioinit_ZL10TagInfoMapcrtstuff.c__JCR_LIST__deregister_tm_clones__do_global_dtors_auxcompleted.9006__do_global_dtors_aux_fini_array_entryframe_dummy__frame_dummy_init_array_entryexif.cgetApp1StartOffsetgetTagNamePRINTF_dumpIfdTablePRINTF.constprop.2_dumpIfdTable.constprop.1parseIFDi.7499__func__.7469JpegDQTOffsettagName.7521App1Header_arm_addsubdf3.o_arm_addsubsf3.oelf-init.c__FRAME_END____JCR_END___DYNAMIC__init_array_end__init_array_start_GLOBAL_OFFSET_TABLE__ZN8nlohmann10basic_jsonISt3mapSt6vectorSsbxydSaNS_14adl_serializerEEC2ERKS4__ZTSSt23_Sp_counted_ptr_inplaceIN8nlohmann6detail20input_buffer_adapterESaIS2_ELN9__gnu_cxx12_Lock_policyE2EE_Znwj@@GLIBCXX_3.4_ZN8nlohmann6detail11parse_errorD1Ev_ZTIN8nlohmann6detail10type_errorEfsync@@GLIBC_2.4_ZN8nlohmann6detail9from_jsonINS_10basic_jsonISt3mapSt6vectorSsbxydSaNS_14adl_serializerEEEjLi0EEEvRKT_RT0__ZSt29_Rb_tree_insert_and_rebalancebPSt18_Rb_tree_node_baseS0_RS_@@GLIBCXX_3.4dirfd@@GLIBC_2.4_ZNSdD2Ev@@GLIBCXX_3.4_ZTVSt9basic_iosIcSt11char_traitsIcEE@@GLIBCXX_3.4_ZN8nlohmann6detail20input_buffer_adapterD1Ev_ZN8nlohmann6detail12out_of_range6createEiRKSs_ZNSt23_Sp_counted_ptr_inplaceIN8nlohmann6detail20input_buffer_adapterESaIS2_ELN9__gnu_cxx12_Lock_policyE2EED0Ev__aeabi_ui2d_ZNKSt8functionIFbiN8nlohmann6detail6parserINS0_10basic_jsonISt3mapSt6vectorSsbxydSaNS0_14adl_serializerEEEE13parse_event_tERS7_EEclEiS9_SA__ZNSs12_M_leak_hardEv@@GLIBCXX_3.4setThumbnailDataOnIfdTableArray_ZNK8nlohmann10basic_jsonISt3mapSt6vectorSsbxydSaNS_14adl_serializerEE3getISsSsLi0EEET0_v_ZTVN8nlohmann6detail12out_of_rangeE_ZN8nlohmann6detail13input_adapterC1IN9__gnu_cxx17__normal_iteratorIPKcSsEELi0EEET_S8__edata_ZNSs4_Rep20_S_empty_rep_storageE@@GLIBCXX_3.4_ZN8nlohmann10basic_jsonISt3mapSt6vectorSsbxydSaNS_14adl_serializerEEixIKcEERS4_PT__ZNSt23_Sp_counted_ptr_inplaceIN8nlohmann6detail20input_buffer_adapterESaIS2_ELN9__gnu_cxx12_Lock_policyE2EE10_M_disposeEvfree@@GLIBC_2.4dumpIfdTableArray_ZN8nlohmann6detail5lexerINS_10basic_jsonISt3mapSt6vectorSsbxydSaNS_14adl_serializerEEEE3getEv_ZNSt8ios_baseC2Ev@@GLIBCXX_3.4_ZTVSt18basic_stringstreamIcSt11char_traitsIcESaIcEE@@GLIBCXX_3.4_ZN8nlohmann6detail11other_errorD1Evfseek@@GLIBC_2.4_ZNSt6vectorIN8nlohmann10basic_jsonISt3mapS_SsbxydSaNS0_14adl_serializerEEESaIS4_EE19_M_emplace_back_auxIJS4_EEEvDpOT__ZNSt8ios_baseD2Ev@@GLIBCXX_3.4_ZN8nlohmann6detail20input_buffer_adapter4readEjj__xstat64@@GLIBC_2.4_IO_stdin_used_ZNSt8_Rb_treeISsSt4pairIKSsN8nlohmann10basic_jsonISt3mapSt6vectorSsbxydSaNS2_14adl_serializerEEEESt10_Select1stIS8_ESt4lessISsESaIS8_EE14_M_create_nodeIIRKS8_EEEPSt13_Rb_tree_nodeIS8_EDpOT__ZTSN8nlohmann6detail20input_buffer_adapterE_ZTIN8nlohmann6detail16invalid_iteratorE_ZNK8nlohmann6detail5lexerINS_10basic_jsonISt3mapSt6vectorSsbxydSaNS_14adl_serializerEEEE16get_token_stringEv_ZSt17__throw_bad_allocv@@GLIBCXX_3.4removeTagNodeFromIfdTableArray_ZSt25__throw_bad_function_callv@@GLIBCXX_3.4.14_ZTSSt16_Sp_counted_baseILN9__gnu_cxx12_Lock_policyE2EE_ZNSt16_Sp_counted_baseILN9__gnu_cxx12_Lock_policyE2EE10_M_destroyEv_ZNSt8_Rb_treeISsSt4pairIKSs10sTagInfo_tESt10_Select1stIS3_ESt4lessISsESaIS3_EE10_M_insert_IRKS3_EESt17_Rb_tree_iteratorIS3_EPSt18_Rb_tree_node_baseSG_OT___cxa_begin_catch@@CXXABI_1.3__floatsisf_ZN8nlohmann6detail11other_errorD2Ev_ZN8nlohmann6detail16invalid_iteratorD1Ev_ZTSN8nlohmann6detail22input_adapter_protocolE_ZTIN8nlohmann6detail11other_errorE_ZNSt8_Rb_treeISsSt4pairIKSsN8nlohmann10basic_jsonISt3mapSt6vectorSsbxydSaNS2_14adl_serializerEEEESt10_Select1stIS8_ESt4lessISsESaIS8_EE22_M_emplace_hint_uniqueIIRKSt21piecewise_construct_tSt5tupleIIOSsEESJ_IIEEEEESt17_Rb_tree_iteratorIS8_ESt23_Rb_tree_const_iteratorIS8_EDpOT___aeabi_ul2dclosedir@@GLIBC_2.4setVerbose_ZN8nlohmann6detail11parse_errorD2Evmain_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_@@GLIBCXX_3.4__cxa_allocate_exception@@CXXABI_1.3__floatsidf_ZN8nlohmann6detail6parserINS_10basic_jsonISt3mapSt6vectorSsbxydSaNS_14adl_serializerEEEED2Ev_ZTVN8nlohmann6detail10type_errorE__subsf3__end___ZNSs6insertEjPKc@@GLIBCXX_3.4_ZN8nlohmann6detail10type_errorD1Ev_ZSt20__throw_length_errorPKc@@GLIBCXX_3.4_ZTVSt16_Sp_counted_baseILN9__gnu_cxx12_Lock_policyE2EE_ZTIN8nlohmann6detail11parse_errorE_ZTVN8nlohmann6detail16invalid_iteratorE_ZNK8nlohmann6detail9exception4whatEv_ZN8nlohmann6detail20input_buffer_adapter13get_characterEv__dso_handleputs@@GLIBC_2.4_ZN8nlohmann10basic_jsonISt3mapSt6vectorSsbxydSaNS_14adl_serializerEE5parseENS_6detail13input_adapterESt8functionIFbiNS5_6parserIS4_E13parse_event_tERS4_EEb_ZNSsC1ERKSs@@GLIBCXX_3.4_ZN8nlohmann6detail11parse_error6createEijRKSs_ZN8nlohmann6detail12out_of_rangeD0Ev_ZNSt6vectorIN8nlohmann10basic_jsonISt3mapS_SsbxydSaNS0_14adl_serializerEEESaIS4_EE14_M_fill_insertEN9__gnu_cxx17__normal_iteratorIPS4_S6_EEjRKS4___subdf3strtoll@@GLIBC_2.4_ZN8nlohmann6detail9exception4nameERKSsi_ZN8nlohmann10basic_jsonISt3mapSt6vectorSsbxydSaNS_14adl_serializerEE10json_valueC1ENS_6detail7value_tE_ZTISt16_Sp_counted_baseILN9__gnu_cxx12_Lock_policyE2EE_ZN8nlohmann6detail5lexerINS_10basic_jsonISt3mapSt6vectorSsbxydSaNS_14adl_serializerEEEE11scan_numberEv_ZNSs6insertEjPKcj@@GLIBCXX_3.4_ZTVN8nlohmann6detail11parse_errorE__floatunsidfsyslog@@GLIBC_2.4_ZTVN8nlohmann6detail22input_adapter_protocolE_ZTVSt15basic_streambufIcSt11char_traitsIcEE@@GLIBCXX_3.4_ZTSN8nlohmann6detail16invalid_iteratorE_ZN8nlohmann6detail12out_of_rangeD1Ev__aeabi_ui2f_ZN8nlohmann6detail9from_jsonINS_10basic_jsonISt3mapSt6vectorSsbxydSaNS_14adl_serializerEEEfLi0EEEvRKT_RT0__ZN8nlohmann6detail9exceptionD2Evmemset@@GLIBC_2.4_ZN8nlohmann6detail11parse_errorD0Evopendir@@GLIBC_2.4_ZTSN8nlohmann6detail11other_errorE_ZNSt13runtime_errorC1ERKSs@@GLIBCXX_3.4_ZSt18_Rb_tree_incrementPSt18_Rb_tree_node_base@@GLIBCXX_3.4__aeabi_frsub_ZTVN10__cxxabiv117__class_type_infoE@@CXXABI_1.3_ZN8nlohmann6detail10type_error6createEiRKSs_ZSt19__throw_logic_errorPKc@@GLIBCXX_3.4nSysLogEn__cxa_free_exception@@CXXABI_1.3__aeabi_fsub__adddf3_ZTSN8nlohmann6detail11parse_errorE_ZN8nlohmann6detail5lexerINS_10basic_jsonISt3mapSt6vectorSsbxydSaNS_14adl_serializerEEEE15token_type_nameENS7_10token_typeE_ZNSs7reserveEj@@GLIBCXX_3.4__bss_end__removeExifSegmentFromJPEGFile__floatdidflocaleconv@@GLIBC_2.4_ZNSs4_Rep10_M_destroyERKSaIcE@@GLIBCXX_3.4abort@@GLIBC_2.4createIfdTableArray_ZNSt16_Sp_counted_baseILN9__gnu_cxx12_Lock_policyE2EE10_M_releaseEvmemmove@@GLIBC_2.4_ZN8nlohmann6detail6parserINS_10basic_jsonISt3mapSt6vectorSsbxydSaNS_14adl_serializerEEEED1Ev_ZNSs12_S_constructIPcEES0_T_S1_RKSaIcESt20forward_iterator_tag_ZN8nlohmann6detail5lexerINS_10basic_jsonISt3mapSt6vectorSsbxydSaNS_14adl_serializerEEEE18next_byte_in_rangeESt16initializer_listIiE_ZNSt6vectorIN8nlohmann10basic_jsonISt3mapS_SsbxydSaNS0_14adl_serializerEEESaIS4_EE19_M_emplace_back_auxIIS4_EEEvDpOT__ZNKSt5ctypeIcE8do_widenEc_ZN8nlohmanneqERKNS_10basic_jsonISt3mapSt6vectorSsbxydSaNS_14adl_serializerEEES6__ZNSt8_Rb_treeISsSt4pairIKSsN8nlohmann10basic_jsonISt3mapSt6vectorSsbxydSaNS2_14adl_serializerEEEESt10_Select1stIS8_ESt4lessISsESaIS8_EE14_M_create_nodeIJRKS8_EEEPSt13_Rb_tree_nodeIS8_EDpOT__ZN8nlohmann6detail16invalid_iterator6createEiRKSs_ZN8nlohmann10basic_jsonISt3mapSt6vectorSsbxydSaNS_14adl_serializerEE10json_valueC2ENS_6detail7value_tE_ZTIN8nlohmann6detail9exceptionE_ZN8nlohmann6detail10type_errorD0Ev__aeabi_dsubstrcpy@@GLIBC_2.4__floatundisfgetIfdType_ZdlPv@@GLIBCXX_3.4__assert_fail@@GLIBC_2.4_ZN8nlohmann6detail16invalid_iteratorD2EvcreateTagInfo_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@@GLIBCXX_3.4_ZN8nlohmann6detail11other_error6createEiRKSsstrtod@@GLIBC_2.4_ZN8nlohmann6detail9exceptionD1Ev_ZNSt13runtime_errorD1Ev@@GLIBCXX_3.4__pthread_key_create@@GLIBC_2.4__extendsfdf2_ZNKSt9type_infoeqERKS_@@GLIBCXX_3.4__floatdisf_ZNK8nlohmann10basic_jsonISt3mapSt6vectorSsbxydSaNS_14adl_serializerEE16assert_invariantEv_ZSt18_Rb_tree_decrementPSt18_Rb_tree_node_base@@GLIBCXX_3.4_ZTSSt19_Sp_make_shared_tagrewind@@GLIBC_2.4freeTagInfo_ZN8nlohmann10basic_jsonISt3mapSt6vectorSsbxydSaNS_14adl_serializerEE10json_value7destroyENS_6detail7value_tE_ZNSs6appendERKSs@@GLIBCXX_3.4fread@@GLIBC_2.4_ZTVN8nlohmann6detail20input_buffer_adapterE_ZNSt8_Rb_treeISsSt4pairIKSsN8nlohmann10basic_jsonISt3mapSt6vectorSsbxydSaNS2_14adl_serializerEEEESt10_Select1stIS8_ESt4lessISsESaIS8_EE7_M_copyEPKSt13_Rb_tree_nodeIS8_EPSG_fileno@@GLIBC_2.4_ZTSN8nlohmann6detail9exceptionE__cxa_end_cleanup@@CXXABI_1.3_ZNSs6appendEPKcj@@GLIBCXX_3.4_ZN8nlohmann10basic_jsonISt3mapSt6vectorSsbxydSaNS_14adl_serializerEED2Ev_ZNSsC1EPKcRKSaIcE@@GLIBCXX_3.4__TMC_END___ZNKSt5ctypeIcE13_M_widen_initEv@@GLIBCXX_3.4.11_ZTIN8nlohmann6detail12out_of_rangeE_ZN8nlohmann6detail5lexerINS_10basic_jsonISt3mapSt6vectorSsbxydSaNS_14adl_serializerEEEE4scanEv_ZSt18_Rb_tree_incrementPKSt18_Rb_tree_node_base@@GLIBCXX_3.4_Jv_RegisterClassesqueryTagNodeIsExist_ZTISt11_Mutex_baseILN9__gnu_cxx12_Lock_policyE2EE_ZTSN8nlohmann6detail10type_errorE_ZNSt23_Sp_counted_ptr_inplaceIN8nlohmann6detail20input_buffer_adapterESaIS2_ELN9__gnu_cxx12_Lock_policyE2EED2Ev__aeabi_l2d_ZTIN8nlohmann6detail22input_adapter_protocolE_ZN8nlohmann6detail20get_arithmetic_valueINS_10basic_jsonISt3mapSt6vectorSsbxydSaNS_14adl_serializerEEEjLi0EEEvRKT_RT0__ZN8nlohmann6detail20input_buffer_adapterD2Ev_ZSt16__throw_bad_castv@@GLIBCXX_3.4_ZN8nlohmann10basic_jsonISt3mapSt6vectorSsbxydSaNS_14adl_serializerEEixEj_ZSt4cout@@GLIBCXX_3.4_ZN8nlohmann6detail13input_adapterC2IN9__gnu_cxx17__normal_iteratorIPKcSsEELi0EEET_S8__ZTVN10__cxxabiv120__si_class_type_infoE@@CXXABI_1.3_ZSt16__ostream_insertIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_PKS3_i@@GLIBCXX_3.4.9_ZNSs6assignERKSs@@GLIBCXX_3.4__aeabi_f2d_ZNSt8_Rb_treeISsSt4pairIKSs10sTagInfo_tESt10_Select1stIS3_ESt4lessISsESaIS3_EE24_M_get_insert_unique_posERS1__ZTSSt11_Mutex_baseILN9__gnu_cxx12_Lock_policyE2EEsetDefaultApp1SegmentHader_ZN8nlohmann6detail5lexerINS_10basic_jsonISt3mapSt6vectorSsbxydSaNS_14adl_serializerEEEE13get_codepointEv_ZNSt23_Sp_counted_ptr_inplaceIN8nlohmann6detail20input_buffer_adapterESaIS2_ELN9__gnu_cxx12_Lock_policyE2EE10_M_destroyEv_ZTISt19_Sp_make_shared_tag__ctype_b_loc@@GLIBC_2.4__bss_start___ZNSt9basic_iosIcSt11char_traitsIcEE4initEPSt15basic_streambufIcS1_E@@GLIBCXX_3.4strtoull@@GLIBC_2.4__data_start_ZN8nlohmann6detail9from_jsonINS_10basic_jsonISt3mapSt6vectorSsbxydSaNS_14adl_serializerEEEiLi0EEEvRKT_RT0__ZNKSt13runtime_error4whatEv@@GLIBCXX_3.4_ZNSt8_Rb_treeISsSt4pairIKSsN8nlohmann10basic_jsonISt3mapSt6vectorSsbxydSaNS2_14adl_serializerEEEESt10_Select1stIS8_ESt4lessISsESaIS8_EE22_M_emplace_hint_uniqueIJRKSt21piecewise_construct_tSt5tupleIJOSsEESJ_IJEEEEESt17_Rb_tree_iteratorIS8_ESt23_Rb_tree_const_iteratorIS8_EDpOT__ZN8nlohmann10basic_jsonISt3mapSt6vectorSsbxydSaNS_14adl_serializerEEC1ERKS4__ZNSt8_Rb_treeISsSt4pairIKSsN8nlohmann10basic_jsonISt3mapSt6vectorSsbxydSaNS2_14adl_serializerEEEESt10_Select1stIS8_ESt4lessISsESaIS8_EE24_M_get_insert_unique_posERS1_ftell@@GLIBC_2.4__aeabi_i2f_ZNSt6localeD1Ev@@GLIBCXX_3.4insertIfdTableToIfdTableArray_ZN8nlohmann6detail12out_of_rangeD2Ev__cxa_rethrow@@CXXABI_1.3fwrite@@GLIBC_2.4_ZNK8nlohmann6detail6parserINS_10basic_jsonISt3mapSt6vectorSsbxydSaNS_14adl_serializerEEEE15throw_exceptionEv_ZNSt8_Rb_treeISsSt4pairIKSs10sTagInfo_tESt10_Select1stIS3_ESt4lessISsESaIS3_EE8_M_eraseEPSt13_Rb_tree_nodeIS3_E__floatundidfmemcpy@@GLIBC_2.4__bss_start_ZTVSt15basic_stringbufIcSt11char_traitsIcESaIcEE@@GLIBCXX_3.4malloc@@GLIBC_2.4getThumbnailDataOnIfdTableArraystrlen@@GLIBC_2.4_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4_ZNSt8ios_base4InitC1Ev@@GLIBCXX_3.4_ZN8nlohmann10basic_jsonISt3mapSt6vectorSsbxydSaNS_14adl_serializerEED1Ev_ZTVN8nlohmann6detail9exceptionEremoveAdobeMetadataSegmentFromJPEGFile__libc_csu_initremoveIfdTableFromIfdTableArrayfclose@@GLIBC_2.4_ZTVN8nlohmann6detail11other_errorEgetIfdTableDump_ZNSs4_Rep9_S_createEjjRKSaIcE@@GLIBCXX_3.4__aeabi_unwind_cpp_pr1@@GCC_3.5__addsf3_ZN8nlohmann6detail9exceptionD0Evstdout@@GLIBC_2.4_ZN8nlohmann6detail11other_errorD0Ev__cxa_end_catch@@CXXABI_1.3_ZTTSt18basic_stringstreamIcSt11char_traitsIcESaIcEE@@GLIBCXX_3.4__aeabi_dadd__gxx_personality_v0@@CXXABI_1.3__aeabi_fadd__aeabi_l2fgetTagInfoFromIfd_ZNSt9basic_iosIcSt11char_traitsIcEE5clearESt12_Ios_Iostate@@GLIBCXX_3.4__cxa_throw@@CXXABI_1.3_ZN8nlohmann10basic_jsonISt3mapSt6vectorSsbxydSaNS_14adl_serializerEEaSES4__ZN8nlohmann6detail5lexerINS_10basic_jsonISt3mapSt6vectorSsbxydSaNS_14adl_serializerEEEE3addEi_ZN8nlohmann6detail6parserINS_10basic_jsonISt3mapSt6vectorSsbxydSaNS_14adl_serializerEEEE14parse_internalEbRS6__ZNSs4swapERSs@@GLIBCXX_3.4_ZNSolsEi@@GLIBCXX_3.4__errno_location@@GLIBC_2.4_ZNSt23_Sp_counted_ptr_inplaceIN8nlohmann6detail20input_buffer_adapterESaIS2_ELN9__gnu_cxx12_Lock_policyE2EE14_M_get_deleterERKSt9type_info_ZNSt23_Sp_counted_ptr_inplaceIN8nlohmann6detail20input_buffer_adapterESaIS2_ELN9__gnu_cxx12_Lock_policyE2EED1Ev_ITM_deregisterTMCloneTablefflush@@GLIBC_2.4fopen64@@GLIBC_2.4memcmp@@GLIBC_2.4updateExifSegmentInJPEGFile__libc_csu_fini_ZN8nlohmann6detail16invalid_iteratorD0Ev__aeabi_unwind_cpp_pr0@@GCC_3.5_ZNSs6appendEPKc@@GLIBCXX_3.4_ZTISt23_Sp_counted_ptr_inplaceIN8nlohmann6detail20input_buffer_adapterESaIS2_ELN9__gnu_cxx12_Lock_policyE2EE_ZNSsC1EPKcjRKSaIcE@@GLIBCXX_3.4_ZN8nlohmann6detail5lexerINS_10basic_jsonISt3mapSt6vectorSsbxydSaNS_14adl_serializerEEEE11scan_stringEv_ZN8nlohmann6detail10type_errorD2Ev_ZNSt9exceptionD2Ev@@GLIBCXX_3.4getTagInfoinsertTagNodeToIfdTableArrayfreeIfdTableArray_ZTSN8nlohmann6detail12out_of_rangeE_ZN8nlohmann6detail20input_buffer_adapterD0Ev__libc_start_main@@GLIBC_2.4_ZTISt9exception@@GLIBCXX_3.4__aeabi_i2d_ZNSt8_Rb_treeISsSt4pairIKSsN8nlohmann10basic_jsonISt3mapSt6vectorSsbxydSaNS2_14adl_serializerEEEESt10_Select1stIS8_ESt4lessISsESaIS8_EE8_M_eraseEPSt13_Rb_tree_nodeIS8_E__gmon_start___ZTVSt23_Sp_counted_ptr_inplaceIN8nlohmann6detail20input_buffer_adapterESaIS2_ELN9__gnu_cxx12_Lock_policyE2EE__aeabi_ul2f__floatunsisf__cxa_pure_virtual@@CXXABI_1.3_ITM_registerTMCloneTable_ZN8nlohmann6detail9from_jsonINS_10basic_jsonISt3mapSt6vectorSsbxydSaNS_14adl_serializerEEEEEvRKT_RNS7_8string_tE_ZTIN8nlohmann6detail20input_buffer_adapterE__aeabi_drsubvsnprintf@@GLIBC_2.4_ZNKSs7compareERKSs@@GLIBCXX_3.4_ZNSs6appendEjc@@GLIBCXX_3.4_ZNSt6vectorIcSaIcEE14_M_fill_insertEN9__gnu_cxx17__normal_iteratorIPcS1_EEjRKc_ZNSt6localeC1Ev@@GLIBCXX_3.4_ZNSt8ios_base4InitD1Ev@@GLIBCXX_3.4.symtab.strtab.shstrtab.interp.note.ABI-tag.hash.dynsym.dynstr.gnu.version.gnu.version_r.rel.dyn.rel.plt.init.text.fini.rodata.ARM.extab.ARM.exidx.eh_frame.init_array.fini_array.jcr.data.rel.ro.dynamic.got.data.bss.comment.ARM.attributes.debug_aranges.debug_info.debug_abbrev.debug_line44#PP 1ppL7 ?zGoTo44c xl BlluL"L" pX"X"d{&&H<<<<(dd,pll mmppppppppqqhssuu@@u@u0@u(phu? u@u&w(4wC@y0" \Getc/0000775000175200017520000000000013557057144012064 5ustar bushnellbushnelletc/ppp/0000775000175200017520000000000013557057144012663 5ustar bushnellbushnelletc/ppp/peers/0000775000175200017520000000000013557057144014001 5ustar bushnellbushnelletc/ppp/peers/quectel-ppp0000664000175200017520000000034313557057144016163 0ustar bushnellbushnell/dev/config_var_port 115200 user "" password "" connect 'chat -s -v -f /etc/ppp/peers/quectel-chat-connect' disconnect 'chat -s -v -f /etc/ppp/peers/quectel-chat-disconnect' hide-password noauth debug defaultroute noipdefault etc/ppp/peers/quectel-chat-disconnect0000664000175200017520000000017513557057144020435 0ustar bushnellbushnellABORT "ERROR" ABORT "NO DIALTONE" SAY "\nSending break to the modem\n" "" +++ "" +++ "" +++ SAY "\nGoodbay\n" etc/ppp/peers/quectel-chat-connect0000664000175200017520000000036013557057144017731 0ustar bushnellbushnellABORT "BUSY" ABORT "NO CARRIER" ABORT "NO DIALTONE" ABORT "ERROR" ABORT "NO ANSWER" TIMEOUT 30 "" AT OK ATE0 OK ATI;+CSUB;+CSQ;+CPIN?;+COPS?;+CGREG?;+CEREG?;&D2 OK AT+CGDCONT=1,"IP","config_var_apn",,0,0 OK config_var_dialcode CONNECT '' etc/shadow0000664000175200017520000000050413557057144013273 0ustar bushnellbushnellroot:$1$4oScCu0n$uiyIafVD4GJWncQGqRvvm/:17532:0:99999:7::: daemon:*:10933:0:99999:7::: bin:*:10933:0:99999:7::: sys:*:10933:0:99999:7::: sync:*:10933:0:99999:7::: mail:*:10933:0:99999:7::: www-data:*:10933:0:99999:7::: operator:*:10933:0:99999:7::: nobody:*:10933:0:99999:7::: dbus:*::::::: mosquitto:*::::::: sshd:*::::::: etc/readme_wifi.txt0000664000175200017520000000031413557057144015076 0ustar bushnellbushnellFor development phase, enable wifi by a) /etc/network/interfaces (rename the interfaces.old to interfaces) b) /etc/wpa_suupplicant.conf (rename the supplicant.conf.ienso file and in that enable wlan0) etc/wpa_supplicant.conf.ienso0000664000175200017520000000023213557057144017075 0ustar bushnellbushnellctrl_interface=/var/run/wpa_supplicant ap_scan=1 network={ ssid="Mural50" psk="UsedtobePhoto" proto=RSN key_mgmt=WPA-PSK pairwise=CCMP auth_alg=OPEN } etc/resolv.conf0000664000175200017520000000015213557057144014243 0ustar bushnellbushnellnameserver 8.8.8.8 nameserver 8.8.4.4 nameserver 209.244.0.3 nameserver 64.6.64.6 nameserver 84.200.69.80 etc/init.d/0000775000175200017520000000000013557057144013251 5ustar bushnellbushnelletc/init.d/S60monit0000775000175200017520000000066513557057144014625 0ustar bushnellbushnell#!/bin/sh # # Start Monit # start() { printf "Starting monit: " /usr/bin/monit /usr/bin/monit start all echo "OK" } stop() { printf "Stopping monit: " /usr/bin/monit quit echo "OK" } case "$1" in start) start ;; stop) stop ;; restart|reload) stop start ;; *) echo "Usage: $0 {start|stop|restart}" exit 1 esac exit $? etc/init.d/S01logging0000775000175200017520000000126113557057144015111 0ustar bushnellbushnell#!/bin/sh # # Start logging # SYSLOGD_ARGS="-n -s 6000 -b 20 -O /var/wtc2.0/messages" KLOGD_ARGS=-n [ -r /etc/default/logging ] && . /etc/default/logging start() { printf "Starting logging: " start-stop-daemon -b -S -q -m -p /var/run/syslogd.pid --exec /sbin/syslogd -- $SYSLOGD_ARGS start-stop-daemon -b -S -q -m -p /var/run/klogd.pid --exec /sbin/klogd -- $KLOGD_ARGS echo "OK" } stop() { printf "Stopping logging: " start-stop-daemon -K -q -p /var/run/syslogd.pid start-stop-daemon -K -q -p /var/run/klogd.pid echo "OK" } case "$1" in start) start ;; stop) stop ;; restart|reload) stop start ;; *) echo "Usage: $0 {start|stop|restart}" exit 1 esac exit $? etc/init.d/S30kmod0000775000175200017520000000404713557057144014424 0ustar bushnellbushnell#!/bin/sh -e ### BEGIN INIT INFO # Provides: kmod # Required-Start: # Required-Stop: # Should-Start: checkroot # Should-Stop: # Default-Start: S # Default-Stop: # Short-Description: Load the modules listed in /etc/modules. # Description: Load the modules listed in /etc/modules. ### END INIT INFO # Silently exit if the kernel does not support modules. [ -f /proc/modules ] || exit 0 [ -x /sbin/modprobe ] || exit 0 [ -f /etc/default/rcS ] && . /etc/default/rcS . /lib/lsb/init-functions PATH='/sbin:/bin' case "$1" in start) if init_is_upstart; then exit 1 fi ;; stop|restart|reload|force-reload) log_warning_msg "Action '$1' is meaningless for this init script" exit 0 ;; *) log_success_msg "Usage: $0 start" exit 1 esac load_module() { local module args module="$1" args="$2" if [ "$VERBOSE" != no ]; then log_action_msg "Loading kernel module $module" modprobe $module $args || true else modprobe $module $args > /dev/null 2>&1 || true fi } modules_files() { local modules_load_dirs='/etc/modules-load.d /run/modules-load.d /usr/local/lib/modules-load.d /usr/lib/modules-load.d /lib/modules-load.d' local processed=' ' local add_etc_modules=true for dir in $modules_load_dirs; do [ -d $dir ] || continue for file in $(run-parts --list --regex='\.conf$' $dir 2> /dev/null || true); do local base=${file##*/} if echo -n "$processed" | grep -qF " $base "; then continue fi if [ "$add_etc_modules" -a -L $file \ -a "$(readlink -f $file)" = /etc/modules ]; then add_etc_modules= fi processed="$processed$base " echo $file done done if [ "$add_etc_modules" ]; then echo /etc/modules fi } if [ "$VERBOSE" = no ]; then log_action_begin_msg 'Loading kernel modules' fi files=$(modules_files) if [ "$files" ] ; then grep -h '^[^#]' $files | while read module args; do [ "$module" ] || continue load_module "$module" "$args" done fi if [ "$VERBOSE" = no ]; then log_action_end_msg 0 fi etc/init.d/S61trailcam0000775000175200017520000000060313557057144015264 0ustar bushnellbushnell#!/bin/sh # # Start Bushnell Wireless Trailcam 2.0 # start() { printf "Starting wireless trail cam: " /opt/wtc2.0/start.sh start echo "OK" } stop() { printf "Stopping wireless trailcam: " /opt/wtc2.0/start.sh stop echo "OK" } case "$1" in start) start ;; stop) stop ;; restart|reload) stop start ;; *) echo "Usage: $0 {start|stop|restart}" exit 1 esac exit $? etc/monitrc0000664000175200017520000000200213557057144013454 0ustar bushnellbushnellset daemon 30 with start delay 5 set logfile /var/log/monit.log set idfile /var/log/monit.id set httpd unixsocket /var/run/monit.sock and allow localhost allow admin:monit # require user 'admin' with password 'monit' ############################################################################### ## Services ############################################################################### check process wtc2-control with pidfile "/var/run/wtc2-control.pid" start program = "/opt/wtc2.0/start.sh start" with timeout 20 seconds stop program = "/opt/wtc2.0/start.sh stop" #check process wtc2-control with pidfile "/var/run/wtc2-control.pid" # start program = "/opt/wtc2.0/start_con.sh start" with timeout 20 seconds # stop program = "/opt/wtc2.0/start_con.sh stop" #check process wtc2-capture with pidfile "/var/run/wtc2-capture.pid" # start program = "/opt/wtc2.0/start_cap.sh start" with timeout 20 seconds # stop program = "/opt/wtc2.0/start_cap.sh stop" etc/udev/0000775000175200017520000000000013557057144013027 5ustar bushnellbushnelletc/udev/rules.d/0000775000175200017520000000000013557057144014403 5ustar bushnellbushnelletc/udev/rules.d/11-sdcard.rules0000664000175200017520000000363213557057144017142 0ustar bushnellbushnellKERNEL!="mmcblk1p1", GOTO="sd_cards_auto_mount_first_partition_end" ACTION=="add", ENV{mount_options}="relatime" # Filesystem specific options ACTION=="add", IMPORT{program}="/sbin/blkid -o udev -p %N" ACTION=="add", ENV{ID_FS_TYPE}=="ntfs", ENV{mount_options}="$env{mount_options},gid=100,dmask=000,fmask=000,utf8" ACTION=="add", ENV{ID_FS_TYPE}== "vfat", ENV{mount_options}="$env{mount_options},gid=100,utf8,rw" ACTION=="add", RUN+="/bin/mkdir -p /media/photos" # automount ntfs filesystems using ntfs-3g driver ACTION=="add", ENV{ID_FS_TYPE}=="ntfs", RUN+="/usr/bin/ntfs-3g /dev/%k /media/photos" # automount not ntfs filesystems ACTION=="add", ENV{ID_FS_TYPE}!="ntfs", RUN+="/bin/mount -o $env{mount_options} /dev/%k /media/photos" ACTION=="remove", RUN+="/bin/umount -l /media/photos", RUN+="/bin/rmdir /media/photos" #--------------------------------------------------------------------------------------------------------------------------------------- LABEL="sd_cards_auto_mount_first_partition_end" KERNEL!="mmcblk[0-9]p[0-9]", GOTO="sd_cards_auto_mount_end" # Global mount options ACTION=="add", ENV{mount_options}="relatime" # Filesystem specific options ACTION=="add", IMPORT{program}="/sbin/blkid -o udev -p %N" ACTION=="add", ENV{ID_FS_TYPE}=="ntfs", ENV{mount_options}="$env{mount_options},gid=100,dmask=000,fmask=000,utf8" ACTION=="add", ENV{ID_FS_TYPE}=="vfat", ENV{mount_options}="$env{mount_options},utf8,gid=100,umask=002" ACTION=="add", RUN+="/bin/mkdir -p /media/sd-%k" ACTION=="add", ENV{ID_FS_TYPE}=="ntfs", RUN+="/usr/bin/ntfs-3g /dev/%k /media/sd-%k" ACTION=="add", ENV{ID_FS_TYPE}!="ntfs",RUN+="/bin/mount -o $env{mount_options} /dev/%k /media/sd-%k" ACTION=="remove", RUN+="/bin/umount -l /media/sd-%k", RUN+="/bin/rmdir /media/sd-%k" ACTION=="remove", RUN+="/usr/bin/mosquitto_pub -t 'sdcard/removed' -m 1" ACTION=="add", RUN+="/usr/bin/mosquitto_pub -t 'sdcard/inserted' -m 1" LABEL="sd_cards_auto_mount_end" etc/apache2/0000775000175200017520000000000013557057144013367 5ustar bushnellbushnelletc/apache2/httpd.conf0000664000175200017520000004450513557057144015371 0ustar bushnellbushnell# This is the main Apache HTTP server configuration file. It contains the # configuration directives that give the server its instructions. # See for detailed information. # In particular, see # # for a discussion of each configuration directive. # # Do NOT simply read the instructions in here without understanding # what they do. They're here only as hints or reminders. If you are unsure # consult the online docs. You have been warned. # # Configuration and logfile names: If the filenames you specify for many # of the server's control files begin with "/" (or "drive:/" for Win32), the # server will use that explicit path. If the filenames do *not* begin # with "/", the value of ServerRoot is prepended -- so "logs/access_log" # with ServerRoot set to "/usr/local/apache2" will be interpreted by the # server as "/usr/local/apache2/logs/access_log", whereas "/logs/access_log" # will be interpreted as '/logs/access_log'. # # ServerRoot: The top of the directory tree under which the server's # configuration, error, and log files are kept. # # Do not add a slash at the end of the directory path. If you point # ServerRoot at a non-local disk, be sure to specify a local disk on the # Mutex directive, if file-based mutexes are used. If you wish to share the # same ServerRoot for multiple httpd daemons, you will need to change at # least PidFile. # ServerRoot "/usr" # # Mutex: Allows you to set the mutex mechanism and mutex file directory # for individual mutexes, or change the global defaults # # Uncomment and change the directory if mutexes are file-based and the default # mutex file directory is not on a local disk or is not appropriate for some # other reason. # # Mutex default:/var/logs # # Listen: Allows you to bind Apache to specific IP addresses and/or # ports, instead of the default. See also the # directive. # # Change this to Listen on specific IP addresses as shown below to # prevent Apache from glomming onto all bound IP addresses. # #Listen 12.34.56.78:80 Listen 80 # # Dynamic Shared Object (DSO) Support # # To be able to use the functionality of a module which was built as a DSO you # have to place corresponding `LoadModule' lines at this location so the # directives contained in it are actually available _before_ they are used. # Statically compiled modules (those listed by `httpd -l') do not need # to be loaded here. # # Example: # LoadModule foo_module modules/mod_foo.so # LoadModule authn_file_module modules/mod_authn_file.so #LoadModule authn_dbm_module modules/mod_authn_dbm.so #LoadModule authn_anon_module modules/mod_authn_anon.so #LoadModule authn_dbd_module modules/mod_authn_dbd.so #LoadModule authn_socache_module modules/mod_authn_socache.so LoadModule authn_core_module modules/mod_authn_core.so LoadModule authz_host_module modules/mod_authz_host.so LoadModule authz_groupfile_module modules/mod_authz_groupfile.so LoadModule authz_user_module modules/mod_authz_user.so #LoadModule authz_dbm_module modules/mod_authz_dbm.so #LoadModule authz_owner_module modules/mod_authz_owner.so #LoadModule authz_dbd_module modules/mod_authz_dbd.so LoadModule authz_core_module modules/mod_authz_core.so LoadModule access_compat_module modules/mod_access_compat.so LoadModule auth_basic_module modules/mod_auth_basic.so #LoadModule auth_form_module modules/mod_auth_form.so #LoadModule auth_digest_module modules/mod_auth_digest.so #LoadModule allowmethods_module modules/mod_allowmethods.so #LoadModule file_cache_module modules/mod_file_cache.so #LoadModule cache_module modules/mod_cache.so #LoadModule cache_disk_module modules/mod_cache_disk.so #LoadModule cache_socache_module modules/mod_cache_socache.so #LoadModule socache_shmcb_module modules/mod_socache_shmcb.so #LoadModule socache_dbm_module modules/mod_socache_dbm.so #LoadModule socache_memcache_module modules/mod_socache_memcache.so #LoadModule watchdog_module modules/mod_watchdog.so #LoadModule macro_module modules/mod_macro.so #LoadModule dbd_module modules/mod_dbd.so #LoadModule dumpio_module modules/mod_dumpio.so #LoadModule echo_module modules/mod_echo.so #LoadModule buffer_module modules/mod_buffer.so #LoadModule data_module modules/mod_data.so #LoadModule ratelimit_module modules/mod_ratelimit.so LoadModule reqtimeout_module modules/mod_reqtimeout.so #LoadModule ext_filter_module modules/mod_ext_filter.so #LoadModule request_module modules/mod_request.so #LoadModule include_module modules/mod_include.so LoadModule filter_module modules/mod_filter.so #LoadModule reflector_module modules/mod_reflector.so #LoadModule substitute_module modules/mod_substitute.so #LoadModule sed_module modules/mod_sed.so #LoadModule charset_lite_module modules/mod_charset_lite.so #LoadModule deflate_module modules/mod_deflate.so LoadModule mime_module modules/mod_mime.so LoadModule log_config_module modules/mod_log_config.so #LoadModule log_debug_module modules/mod_log_debug.so #LoadModule log_forensic_module modules/mod_log_forensic.so #LoadModule logio_module modules/mod_logio.so LoadModule env_module modules/mod_env.so #LoadModule mime_magic_module modules/mod_mime_magic.so #LoadModule expires_module modules/mod_expires.so LoadModule headers_module modules/mod_headers.so #LoadModule usertrack_module modules/mod_usertrack.so #LoadModule unique_id_module modules/mod_unique_id.so LoadModule setenvif_module modules/mod_setenvif.so LoadModule version_module modules/mod_version.so #LoadModule remoteip_module modules/mod_remoteip.so #LoadModule proxy_module modules/mod_proxy.so #LoadModule proxy_connect_module modules/mod_proxy_connect.so #LoadModule proxy_ftp_module modules/mod_proxy_ftp.so #LoadModule proxy_http_module modules/mod_proxy_http.so #LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so #LoadModule proxy_scgi_module modules/mod_proxy_scgi.so #LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so #LoadModule proxy_ajp_module modules/mod_proxy_ajp.so #LoadModule proxy_balancer_module modules/mod_proxy_balancer.so #LoadModule proxy_express_module modules/mod_proxy_express.so #LoadModule proxy_hcheck_module modules/mod_proxy_hcheck.so #LoadModule session_module modules/mod_session.so #LoadModule session_cookie_module modules/mod_session_cookie.so #LoadModule session_crypto_module modules/mod_session_crypto.so #LoadModule session_dbd_module modules/mod_session_dbd.so #LoadModule slotmem_shm_module modules/mod_slotmem_shm.so #LoadModule slotmem_plain_module modules/mod_slotmem_plain.so #LoadModule ssl_module modules/mod_ssl.so #LoadModule dialup_module modules/mod_dialup.so #LoadModule lbmethod_byrequests_module modules/mod_lbmethod_byrequests.so #LoadModule lbmethod_bytraffic_module modules/mod_lbmethod_bytraffic.so #LoadModule lbmethod_bybusyness_module modules/mod_lbmethod_bybusyness.so #LoadModule lbmethod_heartbeat_module modules/mod_lbmethod_heartbeat.so LoadModule unixd_module modules/mod_unixd.so #LoadModule heartbeat_module modules/mod_heartbeat.so #LoadModule heartmonitor_module modules/mod_heartmonitor.so #LoadModule dav_module modules/mod_dav.so LoadModule status_module modules/mod_status.so LoadModule autoindex_module modules/mod_autoindex.so #LoadModule asis_module modules/mod_asis.so #LoadModule info_module modules/mod_info.so LoadModule cgid_module modules/mod_cgid.so #LoadModule dav_fs_module modules/mod_dav_fs.so #LoadModule dav_lock_module modules/mod_dav_lock.so #LoadModule vhost_alias_module modules/mod_vhost_alias.so #LoadModule negotiation_module modules/mod_negotiation.so LoadModule dir_module modules/mod_dir.so #LoadModule actions_module modules/mod_actions.so #LoadModule speling_module modules/mod_speling.so #LoadModule userdir_module modules/mod_userdir.so LoadModule alias_module modules/mod_alias.so #LoadModule rewrite_module modules/mod_rewrite.so # # If you wish httpd to run as a different user or group, you must run # httpd as root initially and it will switch. # # User/Group: The name (or #number) of the user/group to run httpd as. # It is usually good practice to create a dedicated user and group for # running httpd, as with most system services. # User daemon Group daemon # 'Main' server configuration # # The directives in this section set up the values used by the 'main' # server, which responds to any requests that aren't handled by a # definition. These values also provide defaults for # any containers you may define later in the file. # # All of these directives may appear inside containers, # in which case these default settings will be overridden for the # virtual host being defined. # # # ServerAdmin: Your address, where problems with the server should be # e-mailed. This address appears on some server-generated pages, such # as error documents. e.g. admin@your-domain.com # ServerAdmin you@example.com # # ServerName gives the name and port that the server uses to identify itself. # This can often be determined automatically, but we recommend you specify # it explicitly to prevent problems during startup. # # If your host doesn't have a registered DNS name, enter its IP address here. # #ServerName www.example.com:80 # # Deny access to the entirety of your server's filesystem. You must # explicitly permit access to web content directories in other # blocks below. # AllowOverride none Require all denied # # Note that from this point forward you must specifically allow # particular features to be enabled - so if something's not working as # you might expect, make sure that you have specifically enabled it # below. # # # DocumentRoot: The directory out of which you will serve your # documents. By default, all requests are taken from this directory, but # symbolic links and aliases may be used to point to other locations. # DocumentRoot "/usr/htdocs" # # Possible values for the Options directive are "None", "All", # or any combination of: # Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews # # Note that "MultiViews" must be named *explicitly* --- "Options All" # doesn't give it to you. # # The Options directive is both complicated and important. Please see # http://httpd.apache.org/docs/2.4/mod/core.html#options # for more information. # Options Indexes FollowSymLinks ExecCGI # # AllowOverride controls what directives may be placed in .htaccess files. # It can be "All", "None", or any combination of the keywords: # AllowOverride FileInfo AuthConfig Limit # AllowOverride None # # Controls who can get stuff from this server. # Require all granted # # DirectoryIndex: sets the file that Apache will serve if a directory # is requested. # DirectoryIndex index.html # # The following lines prevent .htaccess and .htpasswd files from being # viewed by Web clients. # Require all denied # # ErrorLog: The location of the error log file. # If you do not specify an ErrorLog directive within a # container, error messages relating to that virtual host will be # logged here. If you *do* define an error logfile for a # container, that host's errors will be logged there and not here. # ErrorLog "/var/logs/error_log" # # LogLevel: Control the number of messages logged to the error_log. # Possible values include: debug, info, notice, warn, error, crit, # alert, emerg. # LogLevel warn # # The following directives define some format nicknames for use with # a CustomLog directive (see below). # LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined LogFormat "%h %l %u %t \"%r\" %>s %b" common # You need to enable mod_logio.c to use %I and %O LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio # # The location and format of the access logfile (Common Logfile Format). # If you do not define any access logfiles within a # container, they will be logged here. Contrariwise, if you *do* # define per- access logfiles, transactions will be # logged therein and *not* in this file. # CustomLog "/var/logs/access_log" common # # If you prefer a logfile with access, agent, and referer information # (Combined Logfile Format) you can use the following directive. # #CustomLog "/var/logs/access_log" combined # # Redirect: Allows you to tell clients about documents that used to # exist in your server's namespace, but do not anymore. The client # will make a new request for the document at its new location. # Example: # Redirect permanent /foo http://www.example.com/bar # # Alias: Maps web paths into filesystem paths and is used to # access content that does not live under the DocumentRoot. # Example: # Alias /webpath /full/filesystem/path # # If you include a trailing / on /webpath then the server will # require it to be present in the URL. You will also likely # need to provide a section to allow access to # the filesystem path. # # ScriptAlias: This controls which directories contain server scripts. # ScriptAliases are essentially the same as Aliases, except that # documents in the target directory are treated as applications and # run by the server when requested rather than as documents sent to the # client. The same rules about trailing "/" apply to ScriptAlias # directives as to Alias. # ScriptAlias /cgi-bin/ "/usr/cgi-bin/" # # ScriptSock: On threaded servers, designate the path to the UNIX # socket used to communicate with the CGI daemon of mod_cgid. # #Scriptsock cgisock # # "/usr/cgi-bin" should be changed to whatever your ScriptAliased # CGI directory exists, if you have that configured. # AllowOverride None Options None Require all granted # # TypesConfig points to the file containing the list of mappings from # filename extension to MIME-type. # TypesConfig /etc/apache2/mime.types # # AddType allows you to add to or override the MIME configuration # file specified in TypesConfig for specific file types. # #AddType application/x-gzip .tgz # # AddEncoding allows you to have certain browsers uncompress # information on the fly. Note: Not all browsers support this. # #AddEncoding x-compress .Z #AddEncoding x-gzip .gz .tgz # # If the AddEncoding directives above are commented-out, then you # probably should define those extensions to indicate media types: # AddType application/x-compress .Z AddType application/x-gzip .gz .tgz # # AddHandler allows you to map certain file extensions to "handlers": # actions unrelated to filetype. These can be either built into the server # or added with the Action directive (see below) # # To use CGI scripts outside of ScriptAliased directories: # (You will also need to add "ExecCGI" to the "Options" directive.) # #AddHandler cgi-script .cgi # For type maps (negotiated resources): #AddHandler type-map var # # Filters allow you to process content before it is sent to the client. # # To parse .shtml files for server-side includes (SSI): # (You will also need to add "Includes" to the "Options" directive.) # #AddType text/html .shtml #AddOutputFilter INCLUDES .shtml # # The mod_mime_magic module allows the server to use various hints from the # contents of the file itself to determine its type. The MIMEMagicFile # directive tells the module where the hint definitions are located. # #MIMEMagicFile /etc/apache2/magic # # Customizable error responses come in three flavors: # 1) plain text 2) local redirects 3) external redirects # # Some examples: #ErrorDocument 500 "The server made a boo boo." #ErrorDocument 404 /missing.html #ErrorDocument 404 "/cgi-bin/missing_handler.pl" #ErrorDocument 402 http://www.example.com/subscription_info.html # # # MaxRanges: Maximum number of Ranges in a request before # returning the entire resource, or one of the special # values 'default', 'none' or 'unlimited'. # Default setting is to accept 200 Ranges. #MaxRanges unlimited # # EnableMMAP and EnableSendfile: On systems that support it, # memory-mapping or the sendfile syscall may be used to deliver # files. This usually improves server performance, but must # be turned off when serving from networked-mounted # filesystems or if support for these functions is otherwise # broken on your system. # Defaults: EnableMMAP On, EnableSendfile Off # #EnableMMAP off #EnableSendfile on # Supplemental configuration # # The configuration files in the /etc/apache2/extra/ directory can be # included to add extra features or to modify the default configuration of # the server, or you may simply copy their contents here and change as # necessary. # Server-pool management (MPM specific) #Include /etc/apache2/extra/httpd-mpm.conf # Multi-language error messages #Include /etc/apache2/extra/httpd-multilang-errordoc.conf # Fancy directory listings #Include /etc/apache2/extra/httpd-autoindex.conf # Language settings #Include /etc/apache2/extra/httpd-languages.conf # User home directories #Include /etc/apache2/extra/httpd-userdir.conf # Real-time info on requests and configuration #Include /etc/apache2/extra/httpd-info.conf # Virtual hosts #Include /etc/apache2/extra/httpd-vhosts.conf # Local access to the Apache HTTP Server Manual #Include /etc/apache2/extra/httpd-manual.conf # Distributed authoring and versioning (WebDAV) #Include /etc/apache2/extra/httpd-dav.conf # Various default settings #Include /etc/apache2/extra/httpd-default.conf # Configure mod_proxy_html to understand HTML4/XHTML1 Include /etc/apache2/extra/proxy-html.conf # Secure (SSL/TLS) connections #Include /etc/apache2/extra/httpd-ssl.conf # # Note: The following must must be present to support # starting without SSL on platforms with no /dev/random equivalent # but a statically compiled-in mod_ssl. # SSLRandomSeed startup builtin SSLRandomSeed connect builtin etc/modules0000664000175200017520000000015513557057144013460 0ustar bushnellbushnell# Wifi module 8723bs # Image sensor #imx317 #vfe_v4l2 #Various USB-to-ethernet dongles #ax88179_178a #asix etc/fstab0000664000175200017520000000123213557057144013104 0ustar bushnellbushnell# /dev/root / ext2 rw,noauto 0 1 proc /proc proc defaults 0 0 devpts /dev/pts devpts defaults,gid=5,mode=620 0 0 tmpfs /dev/shm tmpfs mode=0777 0 0 tmpfs /tmp tmpfs mode=1777 0 0 tmpfs /run tmpfs mode=0755,nosuid,nodev 0 0 sysfs /sys sysfs defaults 0 0 #192.168.155.50:/home/fboudreau /mnt/desktop nfs defaults,nolock 0 0 #/dev/mmcblk0p1 /mnt/photos fat defaults 0 0 etc/tmux.conf0000664000175200017520000000711213557057144013731 0ustar bushnellbushnell# of the common GNU screen key bindings to # appropriate tmux key bindings. Note that for some key bindings there is no # tmux analogue and also that this set omits binding some commands available in # tmux but not in screen. # # Note this is only a selection of key bindings and they are in addition to the # normal tmux key bindings. This is intended as an example not as to be used # as-is. # Neovim workaround. Otherwise, after leaving insert mode with ESC results in garbage characters. Need to hit ESC twice... set -s escape-time 0 set -g mouse on set -g mode-keys vi set -g status-position top set -g default-terminal "screen-256color" # Bind appropriate commands similar to screen. # lockscreen ^X x unbind ^X bind ^X lock-server unbind x bind x lock-server # screen ^C c unbind ^C bind ^C new-window unbind c bind c new-window # detach ^D d unbind ^D bind ^D detach # displays * unbind * bind * list-clients # next ^@ ^N sp n unbind ^@ bind ^@ next-window unbind ^N bind ^N next-window unbind " " bind " " next-window unbind n bind n next-window # title A unbind A bind A command-prompt "rename-window %%" # other ^A unbind ^A bind ^A last-window # prev ^H ^P p ^? unbind ^H bind ^H previous-window unbind ^P bind ^P previous-window unbind p bind p previous-window unbind BSpace bind BSpace previous-window # windows ^W w unbind ^W bind ^W list-windows unbind w bind w list-windows # quit \ unbind '\' bind '\' confirm-before "kill-server" # kill K k unbind K bind K confirm-before "kill-window" unbind k bind k confirm-before "kill-window" # redisplay ^L l unbind ^L bind ^L refresh-client unbind l bind l refresh-client # split -v | unbind | bind | split-window # :kB: focus up unbind Tab bind Tab select-pane -t:.+ unbind BTab bind BTab select-pane -t:.- # " windowlist -b unbind '"' bind '"' choose-window # Move window left or right bind-key -n C-S-Left swap-window -t -1 bind-key -n C-S-Right swap-window -t +1 # Switch to next/previous window... bind-key -n S-Right next-window bind-key -n S-Left previous-window set-option -g history-limit 10001 # Setup my windows... #new-session -s 'IENSO' -n ROOT 'sudo su' #new-window -n "Notes/Email" "vim -c VimwikiIndex;bash -i" #split-window "alpine;bash -i" #new-window -n "Trivinci" #split-window #split-window #select-layout tiled #new-window -n "SilVRThread" #split-window #split-window #select-layout tiled #new-window -n "Bushnell" #split-window #split-window #select-layout tiled #new-window -n "OpenCV" # Some problems with this setting. Garbage characters sometime when clicking in another pane. #set mouse-select-pan on set-window-option -g status-left " #S " set-window-option -g status-left-fg black set-window-option -g status-left-bg white set-window-option -g status-right "Load: #(cut -d \" \" -f 1 /proc/loadavg) < %H:%M %d-%b-%y " set-window-option -g status-right-fg black set-window-option -g status-right-bg white set-window-option -g window-status-format " #I: #W " set-window-option -g window-status-current-format " #I: #W " set-window-option -g window-status-current-fg green set-window-option -g window-status-current-bg black # move x clipboard into tmux paste buffer bind C-p run "tmux set-buffer \"$(xclip -o)\"; tmux paste-buffer" # # move tmux copy buffer into x clipboard bind C-y run "tmux save-buffer - | xclip -i" # List of plugins set -g @plugin 'tmux-plugins/tpm' set -g @plugin 'tmux-plugins/tmux-yank' set -g @plugin 'tmux-plugins/tmux-resurrect' set -g @plugin 'tmux-plugins/tmux-logging' # Initialize TMUX plugin manager (keep this line at the very bottom of tmux.conf) run '~/tmux-plugins/tpm/tpm' etc/network/0000775000175200017520000000000013557057144013555 5ustar bushnellbushnelletc/network/interfaces.old0000664000175200017520000000034713557057144016404 0ustar bushnellbushnellauto lo auto eth1 #auto wlan0 iface lo inet loopback iface eth1 inet dhcp iface wlan0 inet dhcp pre-up killall -q wpa_supplicant; wpa_supplicant -B -i wlan0 -c /etc/wpa_supplicant.conf -dd post-down killall -q wpa_supplicant opt/0000755000175200017520000000000013557057144012111 5ustar bushnellbushnellopt/wtc2.0/0000755000175200017520000000000013557057144013126 5ustar bushnellbushnellopt/wtc2.0/src/0000755000175200017520000000000013557057144013715 5ustar bushnellbushnellopt/wtc2.0/src/dem.rb0000644000175200017520000000222413557057144015007 0ustar bushnellbushnell# This module implements the Delegation Event Model (DEM) for # event based programming. There are two parts, event sources # and event listeners. Event sources emit events. Event listeners # register with event sources to receive notifications of events. # # The DEM is implemented as modules. Simply include the EventSource # module in any class that you would like be able to emit events # from. The EventListeners module shows which module EventSource def listeners @listeners ||= [] end def add_listener(listener) listeners << listener end def remove_listener(listener) @listeners.delete(listener) end def notify(event, data=nil) listeners.each{|listener| # Not handling exceptions here. If #handle() does not exist in the listener, # and exception will occure here. Teh even source should handle the excption # appropriately; exit, log, whatever. listener.handle_event(event, data) } end end module EventListener def handle_event(event, data = nil) raise "This method must be implemented by the listener" end end opt/wtc2.0/src/menu.rb0000644000175200017520000017444413557057144015224 0ustar bushnellbushnell require 'env' require 'view' require 'debug' def get_desc(msg) if((str = $desc[msg]) == nil) str = msg else end str end # return the index of previous candidate def sel_prev_candidate(id, idx) childCount = @env.get_candidate_count(id)- 1 #idx=@env.get_selected_idx(id) if(0 < idx) idx = idx - 1 else idx = childCount end #puts "idx=#{idx}" idx end def sel_next_candidate(id, idx) childCount = @env.get_candidate_count(id)- 1 #idx=@env.get_selected_idx(id) if(childCount > idx) idx = idx + 1 else idx = 0 end #puts "idx=#{idx}" idx end def increment_1(lineNo, pos, max) if (lineNo == 1) str = @str1 else str = @str2 end if( str[pos].to_i < max ) str[pos] = (str[pos].ord + 1).chr else str end str end def increment_1_ndigit(lineNo, pos, max, min, ndigit=2) nn = ndigit -1 if (lineNo == 1) str = @str1 else str = @str2 end ii = (str[(pos- nn)..pos]).to_i if(ii >= max) ii = min else ii += 1 end str[(pos-nn)..pos] = (ii.to_s).rjust(ndigit,'0') str end def decrement_1(lineNo, pos, max) if (lineNo == 1) str = @str1 else str = @str2 end if( str[pos].ord > '0'.ord ) str[pos] = (str[pos].ord - 1).chr else if(max == 6) str[pos] = '6' elsif(max == 5) str[pos] = '5' else str[pos] = '9' end end str end def decrement_1_ndigit(lineNo, pos, max, min, ndigit=2) nn = ndigit -1 if (lineNo == 1) str = @str1 else str = @str2 end ii = (str[(pos - nn)..pos]).to_i if(ii <= min) ii = max else ii -= 1 end str[(pos-nn)..pos] = (ii.to_s).rjust(ndigit,'0') str end class MenuNode @@root = nil def initialize(id, parents, *param, &callback) @@root = self unless @@root @id = id @env = nil @parents = parents @child = [] @callback = callback @param = param @selectMenuIdx = 0; if(parents != nil) parents.get_child() << self end end def initialvalue @selectMenuIdx = 0 {:menu=>self, :result=>nil} end def get_root @@root end def get_id @id end def get_value nil end def get_menu() self end def get_return menu = self if(@parents != nil) menu = @parents.get_menu() end menu end def get_child @child end def get_brothers brothers = nil if(@parents != nil) brothers = @parents.get_child() end brothers end def callback if(@callback != nil) @callback.call(@param) end end def execute( ) callback() end def left() res = get_return() if(get_return() == nil) res = self end res end def right() self end def up() end def down() end def get_descript() get_id() end def get_view() hLine1 = {:align=>:center,:id => get_id()} hLine2 = {:align=>:left, :id => get_id()} disc = [hLine1, hLine2] end end class MenuNodeSetup < MenuNode def initialize(id, parents, *param, &callback) #puts '-----------------------------------------------------------menuL0 initialize' super(id, parents, param, callback) end def execute( ) #puts '-----------------------------------------------------------menuL0 execute' res = get_child()[@selectMenuIdx].initialvalue(); super() res end def initialvalue #puts '-----------------------------------------------------------menuL0 initialvalue' super() end def up() #puts '-----------------------------------------------------------menuL0 up' if( @selectMenuIdx > 1) @selectMenuIdx = @selectMenuIdx - 2 else size = get_child().size - 1 if(size%2 == 0) @selectMenuIdx = size - @selectMenuIdx elsif(@selectMenuIdx == 0) @selectMenuIdx = size - 1 elsif(@selectMenuIdx == 1) @selectMenuIdx = size end end end def down() #puts '-----------------------------------------------------------menuL0 down' size = get_child().size - 1 if( @selectMenuIdx < (size - 1)) @selectMenuIdx = @selectMenuIdx + 2 else @selectMenuIdx = @selectMenuIdx%2 end end def left() #puts '-----------------------------------------------------------menuL0 left' idx_bak = @selectMenuIdx if(@selectMenuIdx%2 == 0) @selectMenuIdx += 1 else @selectMenuIdx -= 1 end if(@selectMenuIdx > get_child().size - 1) @selectMenuIdx = idx_bak end self end def right() #puts '-----------------------------------------------------------menuL0 right' left() end def make_str(str1, str2) str2_len = 0 if(str2 != nil) str2_len = str2.length; end if(str1 != nil) str1_len = 16 - str2_len; str = str1.ljust(str1_len) str += str2 if(str2 != nil) {:str=>str,:str2_start=>str1_len} else {:str=>"",:str2_start=>0} end end def get_view() idx = @selectMenuIdx % 4 idx_start = @selectMenuIdx & 0xFC cursor = 0 child = get_child()[idx_start..idx_start + 3] child0 = child[0].get_id() if(child[0] != nil) child1 = child[1].get_id() if(child[1] != nil) child2 = child[2].get_id() if(child[2] != nil) child3 = child[3].get_id() if(child[3] != nil) str1 = make_str(get_desc(child0), get_desc(child1)) str2 = make_str(get_desc(child2), get_desc(child3)) if(idx == 1) cursor = str1[:str2_start] elsif(idx == 2) cursor = 16 elsif(idx == 3) cursor = str2[:str2_start] + 16 end hLine1 = {:align=>:left,:id =>str1[:str]} hLine2 = {:align=>:left, :id =>str2[:str], :cursor=>cursor} disc = [hLine1, hLine2] end end class MenuNodeSub < MenuNode include EventSource def initialize(id, parents, *param, &callback) #puts '-----------------------------------------------------------NodeSub initialize' super(id, parents, param, callback) end def execute( ) Log4Ienso.log.P_INFO("-----------------------------------------------------------NodeSub execute") child = get_child()[@selectMenuIdx] #if(child.kind_of?(MenuNodeEnvValue)) if( (child.kind_of?(MenuNodeEnvValue) ) || (child.kind_of?(MenuNodeCallbackOnExecute) ) ) res = child.execute() right() super() elsif((child.kind_of?(MenuNodeFieldScan) ) || (child.kind_of?(MenuNodeEnvTimeOfOperation) ) ) if(child.get_idx == 0) # 'off' res = child.execute(true) right() super() else res = child.initialvalue(); # 'on' end elsif(child.kind_of?(MenuNodeEnvPirMode) ) if(child.get_idx != 3) # 3='timer' res = child.execute(true) right() super() else res = child.initialvalue() # 'timeron' child.set_idx(3) sleep(0.1) ret = {} ret[:mode] = 0x04 notify('menu/pir_mode', ret) end else res = child.initialvalue(); end res end def initialvalue #puts '-----------------------------------------------------------NodeSub initial value' get_child().each{ |child| child.initialvalue() } super() end def left() #puts '-----------------------------------------------------------NodeSub left' child = get_child()[@selectMenuIdx] child.initialvalue() childCount = get_child().count - 1 if(0 < @selectMenuIdx) @selectMenuIdx = @selectMenuIdx - 1 else @selectMenuIdx = childCount end end def right() #puts '-----------------------------------------------------------NodeSub right' child = get_child()[@selectMenuIdx] child.initialvalue() childCount = get_child().count - 1 if(childCount > @selectMenuIdx) @selectMenuIdx = @selectMenuIdx + 1 else @selectMenuIdx = 0 end end def up() #puts '-----------------------------------------------------------NodeSub up' child = get_child()[@selectMenuIdx] #if(child.kind_of?(MenuNodeEnvValue)) if(child.kind_of?(MenuNodeEnvValue) ) child.up() elsif((child.kind_of?(MenuNodeFieldScan) ) || (child.kind_of?(MenuNodeEnvTimeOfOperation) ) || (child.kind_of?(MenuNodeEnvPirMode) )) child.up_main() #puts('up in sub menu') #if(@env.get_selected_idx('field_scan') == 1) #@env.save_env('field_scan', 0) #else # @env.save_env('field_scan', 1) #end end end def down() #puts '-----------------------------------------------------------NodeSub down' child = get_child()[@selectMenuIdx] #if(child.kind_of?(MenuNodeEnvValue)) if(child.kind_of?(MenuNodeEnvValue)) child.down() elsif((child.kind_of?(MenuNodeFieldScan) ) || (child.kind_of?(MenuNodeEnvTimeOfOperation) ) || (child.kind_of?(MenuNodeEnvPirMode) )) #puts('down in sub menu') child.down_main() end end def get_view() #puts '-----------------------------------------------------------NodeSub get_view' cursor_point = nil child = get_child()[@selectMenuIdx] childCount = get_child().count - 1 if(childCount > @selectMenuIdx) idx = @selectMenuIdx + 1 else idx = 0 end next_child = get_child()[idx] if( child.get_value() != nil) str1 = "#{get_desc(child.get_id())}: #{get_desc(child.get_value())}" #if(child.kind_of?(MenuNodeEnvValue)) if( (child.kind_of?(MenuNodeEnvValue)) || (child.kind_of?(MenuNodeFieldScan)) || (child.kind_of?(MenuNodeEnvTimeOfOperation)) || (child.kind_of?(MenuNodeVideoLength)) || (child.kind_of?(MenuNodeEnvPirMode) )) cursor_point = get_desc(child.get_id()).size + 2 if(cursor_point > 16) cursor_point = nil end end else str1 = "#{get_desc(child.get_id())}" end if(next_child.get_value() != nil) str2 = "#{get_desc(next_child.get_id())}: #{get_desc(next_child.get_value())}" else str2 = "#{get_desc(next_child.get_id())}" end hLine1 = {:align=>:left,:id =>str1} hLine2 = {:align=>:left, :id =>str2, :cursor=>cursor_point} disc = [hLine1, hLine2] disc end end class MenuNodeEnv < MenuNode def initialize(id, parents, env, *param, &callback) super(id, parents, param, callback) @env = env end def execute( ) @env.save_env(get_id(), @selectMenuIdx) res = {:menu=>get_return(), :result=>"Success"} super() res end def initialvalue env_idx = @env.get_selected_idx(get_id()) res = {:menu=>self, :result=>nil} if(env_idx == nil) res[:menu] = get_return() res[:result] = "Not Support" else @selectMenuIdx = env_idx end #puts @selectMenuIdx res end def up() childCount = @env.get_candidate_count(get_id()) - 1 if(0 < @selectMenuIdx) @selectMenuIdx = @selectMenuIdx - 1 else @selectMenuIdx = childCount end end def down() childCount = @env.get_candidate_count(get_id()) - 1 if(childCount > @selectMenuIdx) @selectMenuIdx = @selectMenuIdx + 1 else @selectMenuIdx = 0 end end def get_view() #puts get_id() #puts @selectMenuIdx #puts @env.get_candidate(get_id())[@selectMenuIdx] hLine1 = {:align=>:center,:id => get_id()} hLine2 = {:align=>:right, :id => @env.get_candidate(get_id())[@selectMenuIdx]} disc = [hLine1, hLine2] end end class MenuNodeEnvTracking < MenuNode def initialize(id, parents, env, *param, &callback) super(id, parents, param, callback) @env = env @exitstate = false end def execute( ) @env.save_env(get_id(), @selectMenuIdx) res = {:menu=>get_return(), :result=>"Success"} super() res end def initialvalue env_idx = @env.get_selected_idx(get_id()) if env_idx == 0 @exitstate = true end res = {:menu=>self, :result=>nil} if(env_idx == nil) res[:menu] = get_return() res[:result] = "Not Support" else @selectMenuIdx = env_idx end #puts @selectMenuIdx res end def up() return if @exitstate == true childCount = @env.get_candidate_count(get_id()) - 1 if(0 < @selectMenuIdx) @selectMenuIdx = @selectMenuIdx - 1 else @selectMenuIdx = childCount end end def down() return if @exitstate == true childCount = @env.get_candidate_count(get_id()) - 1 if(childCount > @selectMenuIdx) @selectMenuIdx = @selectMenuIdx + 1 else @selectMenuIdx = 0 end end def get_view() #puts get_id() #puts @selectMenuIdx #puts @env.get_candidate(get_id())[@selectMenuIdx] hLine1 = {:align=>:center,:id => get_id()} hLine2 = {:align=>:right, :id => @env.get_candidate(get_id())[@selectMenuIdx]} disc = [hLine1, hLine2] end end class MenuNodeEnvValue < MenuNodeEnv def initialize(id, parents, env, *param, &callback) super(id, parents, param, callback) @env = env end def execute( ) res = {:menu=>get_return(), :result=>"saved"} if (@selectMenuIdx != nil) @env.save_env(get_id(), @selectMenuIdx) else res[:result] = "n/a" end super() res end def initialvalue env_idx = @env.get_selected_idx(get_id()) res = {:menu=>get_return(), :result=>nil} @selectMenuIdx = env_idx res end def down() if (@selectMenuIdx != nil) childCount = @env.get_candidate_count(get_id()) - 1 if(0 < @selectMenuIdx) @selectMenuIdx = @selectMenuIdx - 1 else @selectMenuIdx = childCount end end end def up() if (@selectMenuIdx != nil) childCount = @env.get_candidate_count(get_id()) - 1 if(childCount > @selectMenuIdx) @selectMenuIdx = @selectMenuIdx + 1 else @selectMenuIdx = 0 end end end def get_value ret = "n/a" if(@selectMenuIdx != nil) ret = @env.get_candidate(get_id())[@selectMenuIdx] end ret end end class MenuNodeVideoLength < MenuNodeEnv def initialize(id, parents, env, *param, &callback) super(id, parents, param, callback) @env = env @str1 = " #{@env.get_env('movie_length')}SEC" @str2 = " #{@env.get_env('movie_length')} " end def initialvalue #puts '------------------------------------------------------------------------- initial value video length' @line = 2 @str1 = "#{get_desc("movie_length")}:#{@env.get_env('movie_length')}SEC" @str2[11..12] = @env.get_env('movie_length') #read_values(@env.get_selected_idx('movie_length')) res = {:menu=>self, :result=>nil} @cursor_point = 12 + 16 res end def left() if( @cursor_point == (12+16)) @cursor_point = 11 + 16 else @cursor_point = 12 +16 end end def right() left() end def up() cursor_point = @cursor_point - 16 if(cursor_point == (12)) if(@str2[11] != '6') @str2 = increment_1(2, cursor_point, 9) end else if(@str2[12] == '0') @str2 = increment_1(2, cursor_point, 6) else @str2 = increment_1(2, cursor_point, 5) end end end def down() cursor_point = @cursor_point - 16 if(cursor_point == (12)) if(@str2[11] != '6') @str2 = decrement_1(2, cursor_point, 9) end else if(@str2[12] == '0') @str2 = decrement_1(2, cursor_point, 6) else @str2 = decrement_1(2, cursor_point, 5) end end end def execute( ) res = {:menu=>get_return(), :result=>"saved"} @env.save_env_val('movie_length', @str2[11..12]) callback() res end def get_value #puts '------------------------------------------------------------------------- get_value video length' ret = @env.get_env('movie_length') ret end def get_view() #puts '------------------------------------------------------------------------- too get_view' hLine1 = {:align=>:left,:id => @str1} hLine2 = {:align=>:left, :id => @str2, :cursor => (@cursor_point)} disc = [hLine1, hLine2] end end class MenuNodeFieldScan < MenuNodeEnv include EventSource def initialize(id, parents, env, *param, &callback) #puts '-------------------------------------------------------------------------f1' super(id, parents, param, callback) @env = env @selected_scan_ab_idx=0 @selected_interval_idx=0 @selectMenuIdx = @env.get_selected_idx('field_scan') end def get_idx() #puts '-------------------------------------------------------------------------f2' @selectMenuIdx end def execute(mainFlag = false ) #puts '-------------------------------------------------------------------------f3' res = {:menu=>get_return(), :result=>"saved"} if(mainFlag) if (@selectMenuIdx != nil) @env.save_env(get_id(), @selectMenuIdx) notify('menu/field_scan') else res[:result] = "n/a" end else if (@selected_scan_ab_idx != nil) @env.save_env('scan_ab', @selected_scan_ab_idx) if (@selected_scan_ab_idx == 0) @env.save_env('interval_a', @selected_interval_idx) @env.save_env_val('start_time_a', @str2[1..5]) @env.save_env_val('end_time_a', @str2[9..13]) else @env.save_env('interval_b', @selected_interval_idx) @env.save_env_val('start_time_b', @str2[1..5]) @env.save_env_val('end_time_b', @str2[9..13]) end notify('menu/field_scan') else res[:result] = "n/a" end end @env.save_env(get_id(), @selectMenuIdx) super() res end # populate the variable @str1, @str2 based on the selection of scan_ab # input=index of selected candidate def read_values(scan_ab) #puts '-------------------------------------------------------------------------f4' @selected_scan_ab_idx=scan_ab if( @selected_scan_ab_idx == 0) @selected_interval_idx=@env.get_selected_idx('interval_a') str_interval=get_desc(@env.get_candidate('interval_a')[@selected_interval_idx]) str_strt=@env.get_env('start_time_a') str_end=@env.get_env('end_time_a') else @selected_interval_idx=@env.get_selected_idx('interval_b') str_interval=get_desc(@env.get_candidate('interval_b')[@selected_interval_idx]) str_strt=@env.get_env('start_time_b') str_end=@env.get_env('end_time_b') end @str1="#{get_desc("scan_ab")}:#{get_desc(@env.get_candidate('scan_ab')[@selected_scan_ab_idx])} #{get_desc("interval")} #{str_interval}" @str2=" #{str_strt} - #{str_end}" #puts "@str1=#{@str1}" #puts "@str2=#{@str2}" #get_desc(@env.get_env_value('scan_ab')) end def initialvalue #puts '-------------------------------------------------------------------------f5' @line = 1 read_values(@env.get_selected_idx('scan_ab')) res = {:menu=>self, :result=>nil} @cursor_point = 5 res end def up_main() #puts '-------------------------------------------------------------------------f6' if (@selectMenuIdx != nil) @selectMenuIdx=sel_prev_candidate(get_id(), @selectMenuIdx) end end def down_main() #puts '-------------------------------------------------------------------------f7' if (@selectMenuIdx != nil) @selectMenuIdx=sel_next_candidate(get_id(), @selectMenuIdx) end end def up() #puts '-------------------------------------------------------------------------f8' #puts "up function" if(@line == 1) cursor_point = @cursor_point str = @str1 if( cursor_point == 5) read_values(sel_prev_candidate('scan_ab', @selected_scan_ab_idx)) else @selected_interval_idx = sel_prev_candidate('interval_a', @selected_interval_idx) @str1[12..14]=get_desc(@env.get_candidate('interval_a')[@selected_interval_idx]) end else cursor_point = @cursor_point - 16 str = @str2 if( (cursor_point == 2) || (cursor_point == 10) ) str = increment_1_ndigit(2, cursor_point, 23, 0, 2) elsif( (cursor_point == 1) || (cursor_point == 9) ) if( str[cursor_point+1].ord > '3'.ord ) str = increment_1(2, cursor_point, 1) else str = increment_1(2, cursor_point, 2) end elsif( (cursor_point == 5) || (cursor_point == 13) ) str = increment_1_ndigit(2, cursor_point, 59, 0, 2) elsif( (cursor_point == 4) || (cursor_point == 12) ) str = increment_1(2, cursor_point, 5) else end @str2=str #puts (@str2) # HH:MM - HH:MM #012345678901234 end end def down() #puts '-------------------------------------------------------------------------f9' #puts "down function" if(@line == 1) cursor_point = @cursor_point str = @str1 if( cursor_point == 5) read_values(sel_prev_candidate('scan_ab', @selected_scan_ab_idx)) else @selected_interval_idx = sel_next_candidate('interval_a', @selected_interval_idx) @str1[12..14]=get_desc(@env.get_candidate('interval_a')[@selected_interval_idx]) end else cursor_point = @cursor_point - 16 str = @str2 if( str[cursor_point].ord > '0'.ord ) str[cursor_point] = (str[cursor_point].ord - 1).chr elsif( (cursor_point == 2) || (cursor_point == 10) ) str = decrement_1_ndigit(2, cursor_point, 23, 0, 2) elsif( (cursor_point == 5) || (cursor_point == 13) ) str = decrement_1_ndigit(2, cursor_point, 59, 0, 2) elsif( (cursor_point == 1) || (cursor_point == 9) ) if( str[cursor_point+1].ord > '3'.ord ) str[cursor_point] = '1' else str[cursor_point] = '2' end else str[cursor_point] = '5' end @str2=str #puts (@str2) # HH:MM - HH:MM #012345678901234 end end def left() #puts '-------------------------------------------------------------------------f10' if(@line == 1) if(@cursor_point == 5) @line = 2 @cursor_point = 29 else @cursor_point = 5 end else if((@cursor_point == 29) || (@cursor_point == 21) ) @cursor_point -= 3 elsif(@cursor_point == 18) @line = 1 @cursor_point = 13 else @cursor_point = 21 end end end def right() #puts '-------------------------------------------------------------------------f11' if(@line == 1) if(@cursor_point == 5) @cursor_point = 13 else @line = 2 @cursor_point = 18 end else if((@cursor_point == 18) || (@cursor_point == 26) ) @cursor_point += 3 elsif(@cursor_point == 29) @line = 1 @cursor_point = 5 else @cursor_point = 26 end end end def get_value #puts '-------------------------------------------------------------------------f12' ret = "n/a" if(@selectMenuIdx != nil) ret = @env.get_candidate(get_id())[@selectMenuIdx] end ret end def get_view() #puts '-------------------------------------------------------------------------f13' hLine1 = {:align=>:left,:id => @str1} hLine2 = {:align=>:left, :id => @str2, :cursor => (@cursor_point)} disc = [hLine1, hLine2] end end class MenuNodeSetTime get_return(), :result=>"Success"} @selectMenuIdx = 0; callback() res end def initialvalue #puts '-----------------------------------------------------------set_time initial_value' @line = 1 res = {:menu=>self, :result=>nil} @str1 = Time.now.strftime('YEAR %m/%d/%Y') @str2 = Time.now.strftime('TIME %H:%M') @cursor_point = 6 res end def get_view() #puts '-----------------------------------------------------------set_time get_view ' #puts get_id() #puts @selectMenuIdx #puts @env.get_candidate(get_id())[@selectMenuIdx] hLine1 = {:align=>:left,:id => @str1} hLine2 = {:align=>:left, :id => @str2, :cursor => (@cursor_point)} disc = [hLine1, hLine2] end def get_value #puts '-----------------------------------------------------------set_time get_value ' Time.now.strftime('%H:%M') end def down() #puts '-----------------------------------------------------------set_time down ' #puts "DOWN" if(@line == 1) cursor_point = @cursor_point str = @str1 if( cursor_point == 14) str = decrement_1_ndigit(1, cursor_point, 2030, 2018, 4) elsif( cursor_point == 6) str = decrement_1_ndigit(1, cursor_point, 12, 1, 2) elsif( cursor_point == 9) max = get_max_day(str[5..6].to_i) str = decrement_1_ndigit(1, cursor_point, max, 1, 2) elsif( cursor_point == 8) if( str[cursor_point].ord > '0'.ord ) str[cursor_point] = (str[cursor_point].ord - 1).chr else str[cursor_point] = '2' end else end @str1=str else cursor_point = @cursor_point - 16 str = @str2 if( str[cursor_point].ord > '0'.ord ) str[cursor_point] = (str[cursor_point].ord - 1).chr elsif( cursor_point == 7) str = decrement_1_ndigit(2, cursor_point, 23, 0, 2) elsif( cursor_point == 10) str = decrement_1_ndigit(2, cursor_point, 59, 0 ,2) elsif( cursor_point == 6) if( str[cursor_point+1].ord > '3'.ord ) str[cursor_point] = '1' else str[cursor_point] = '2' end else str[cursor_point] = '5' end @str2=str end #Time.new("#{@str1[11..14]}".to_i, "#{@str1[5..6]}".to_i, "#{@str1[8..9]}".to_i, "#{@str2[6..7]}".to_i, "#{@str2[9..10]}".to_i,0) # loop do # begin # if( str[cursor_point].ord > '0'.ord ) # str[cursor_point] = (str[cursor_point].ord - 1).chr # else # str[cursor_point] = '9' # end #YEAR mm/dd/yyyy #012345678901234 #TIME HH/MM # Time.new("#{@str1[11..14]}".to_i, "#{@str1[5..6]}".to_i, "#{@str1[8..9]}".to_i, "#{@str2[6..7]}".to_i, "#{@str2[9..10]}".to_i,0) # break; # rescue => exception # puts "c exception [#{str[cursor_point]}]" # end # end end def get_max_day(mm = 1) if(mm == 2) ret = 28 elsif( mm ==4 || mm ==6 || mm ==9 || mm ==11) ret = 30 else ret = 31 end ret end def up() if(@line == 1) cursor_point = @cursor_point str = @str1 if( cursor_point == 14) str = increment_1_ndigit(1, cursor_point, 2030, 2018, 4) else if( cursor_point == 9) max = get_max_day(str[5..6].to_i) str = increment_1_ndigit(1, cursor_point, max, 1, 2) elsif( cursor_point == 6) str = increment_1_ndigit(1, cursor_point, 12, 1, 2) elsif( cursor_point == 8) if( str[cursor_point+1].ord > '1'.ord ) str = increment_1(1, cursor_point, 2) else str = increment_1(1, cursor_point, 3) end else end end @str1=str else cursor_point = @cursor_point - 16 str = @str2 if( cursor_point == 7) str = increment_1_ndigit(2, cursor_point, 23, 0, 2) elsif( cursor_point == 6) if( str[cursor_point+1].ord > '3'.ord ) str = increment_1(2, cursor_point, 1) else str = increment_1(2, cursor_point, 2) end elsif( cursor_point == 10) str = increment_1_ndigit(2, cursor_point, 59, 0, 2) elsif( cursor_point == 9) str = increment_1(2, cursor_point, 5) else end @str2=str end #Time.new("#{@str1[11..14]}".to_i, "#{@str1[5..6]}".to_i, "#{@str1[8..9]}".to_i, "#{@str2[6..7]}".to_i, "#{@str2[9..10]}".to_i,0) # loop do # begin # if( str[cursor_point].ord < '9'.ord ) # str[cursor_point] = (str[cursor_point].ord + 1).chr # else # str[cursor_point] = '0' # end #YEAR mm/dd/yyyy #012345678901234 #TIME HH/MM #678901234567890 # Time.new("#{@str1[11..14]}".to_i, "#{@str1[5..6]}".to_i, "#{@str1[8..9]}".to_i, "#{@str2[6..7]}".to_i, "#{@str2[9..10]}".to_i,0) # break; # rescue => exception #puts "c [#{str[cursor_point]}]" # end end def left() #puts '-----------------------------------------------------------set_time left ' if(@line == 1) if(@cursor_point == 6) @line = 2 @cursor_point = 26 elsif(@cursor_point == 14) @cursor_point = 9 else @cursor_point = 6 end else if(@cursor_point == 23) @line = 1 @cursor_point = 14 else @cursor_point = 23 end end end def right() #puts '-----------------------------------------------------------set_time right ' if(@line == 1) if(@cursor_point == 14) @line = 2 @cursor_point = 23 elsif(@cursor_point == 6) @cursor_point = 9 else @cursor_point = 14 end else if(@cursor_point == 26) @line = 1 @cursor_point = 6 else @cursor_point = 26 end end end end class MenuNodeEnvTimeOfOperation < MenuNodeEnv include EventSource def get_return @env.save_env('time_ofoperation.enable', @selectMenuIdx) #puts "===============================too get_return" super end def get_return2 menu = self #if(@parents != nil) #menu = @parents.get_menu() #end menu end def read_time_offon(idx) #puts '-------------------------------------------------------------------------too read time' if(idx == 0) str=@env.get_env('time_ofoperation.off_on') else str=@env.get_env('time_ofoperation.time') end str1=str[@selected_days_idx] if str != nil str1=str1.split('/') str1=str1[@selected_block_idx] if str1 != nil str1 end def check_time() ret = false entered_time = @str2[11..15] str=@env.get_env('time_ofoperation.time') str1=str[@selected_days_idx] str2=str1.split('/') prev_time='00:00' next_time='23:59' if(@selected_block_idx > 0) prev_time = str2[@selected_block_idx - 1] end if(@selected_block_idx < 3) next_time = str2[@selected_block_idx + 1] end if( (entered_time < next_time) & (entered_time > prev_time)) ret = true end #puts("============ prev_time=#{prev_time} time=#{entered_time} next_time=#{next_time} return=#{ret}") ret end def read_values() #puts '-------------------------------------------------------------------------too read values' id="blk#{@selected_block_idx}" str2=get_desc(id) @str1="#{get_desc("days")}: #{get_desc(@env.get_candidate2('time_ofoperation.days')[@selected_days_idx])} #{str2}" if(read_time_offon(0) == '0') str1=get_desc("off") @selected_days_onoff_idx = 0 else str1=get_desc("on") str1="#{str1} " @selected_days_onoff_idx = 1 end str2= read_time_offon(1) @str2="#{get_desc('cam')} #{str1} #{str2}" #puts "@str1=#{@str1}" #puts "@str2=#{@str2}" end def initialvalue #puts '------------------------------------------------------------------------- too initial value' @line = 2 @selected_days_idx=0 @selected_block_idx=0 read_values() res = {:menu=>self, :result=>nil} @cursor_point = 4+16 res end def initialize(id, parents, env, *param, &callback) #puts '-------------------------------------------------------------------------too initialize' super(id, parents, param, callback) @env = env @selected_days_idx=0 @selected_block_idx=0 @selected_days_onoff_idx=0 str=@env.get_env('time_ofoperation.enable') if(str == 'off') @selectMenuIdx = 0 else @selectMenuIdx = 1 end end def get_idx() #puts '-------------------------------------------------------------------------too get_idx' @selectMenuIdx end def execute(mainFlag = false ) #puts '------------------------------------------------------------------------- too execute' if(mainFlag) res = {:menu=>get_return(), :result=>"saved"} @env.save_env('time_ofoperation.enable', @selectMenuIdx) callback() res else save_flag = false offon=read_time_offon(0).to_i time=read_time_offon(1) if(offon != @selected_days_onoff_idx) save_flag = true #puts '-----------------------on/off changed so save it' str=@env.get_env('time_ofoperation.off_on') if(@selected_days_onoff_idx ==0) str[@selected_days_idx][@selected_block_idx*2] = '0' else str[@selected_days_idx][@selected_block_idx*2] = '1' end @env.save_env_val('time_ofoperation.off_on',str) #puts("-----------------------------------new operation offon=#{str}") end if(time != @str2[11..15]) if(check_time() == true) save_flag = true #puts '-----------------------time changed so save it' str=@env.get_env('time_ofoperation.time') str[@selected_days_idx] [@selected_block_idx*6..(@selected_block_idx*6)+4]= @str2[11..15] @env.save_env_val('time_ofoperation.time',str) #puts("-----------------------------------new operation time =#{str}") end end if(@selected_block_idx < 3) @selected_block_idx +=1 else @selected_block_idx = 0 if( @selected_days_idx < 2) @selected_days_idx +=1 else @selected_days_idx = 0 end end read_values() if(save_flag == true) res = {:menu=>get_return2(), :result=>"saved"} #@selectMenuIdx = 0; notify('menu/time_ofoperation') res end end end def up_main() if(@selectMenuIdx ==0) @selectMenuIdx = 1 else @selectMenuIdx = 0 end end def down_main() up_main() end def up() #puts '------------------------------------------------------------------------- too up' #puts "up function" cursor_point = @cursor_point - 16 str = @str2 if( cursor_point == 4) if(@selected_days_onoff_idx == 0) @selected_days_onoff_idx = 1 @str2[4..6] = "#{get_desc("on")} " else @selected_days_onoff_idx = 0 @str2[4..6] = get_desc("off") end #read_values() else if (cursor_point == 12) if( str[cursor_point-1].ord > '1'.ord ) str = increment_1(2, cursor_point, 3) else str = increment_1(2, cursor_point, 9) end elsif( cursor_point == 11) if( str[cursor_point+1].ord > '3'.ord ) str = increment_1(2, cursor_point, 1) else str = increment_1(2, cursor_point, 2) end elsif( cursor_point == 15 ) str = increment_1(2, cursor_point, 9) elsif(cursor_point == 14) str = increment_1(2, cursor_point, 5) #else end @str2=str end #puts (@str2) # HH:MM - HH:MM #012345678901234 end def down() #puts '------------------------------------------------------------------------- too down' #puts "down function" cursor_point = @cursor_point - 16 str = @str2 if( cursor_point == 4) if(@selected_days_onoff_idx == 0) @selected_days_onoff_idx = 1 @str2[4..6] = "#{get_desc("on")} " else @selected_days_onoff_idx = 0 @str2[4..6] = get_desc("off") end #read_values() else if( str[cursor_point].ord > '0'.ord ) str[cursor_point] = (str[cursor_point].ord - 1).chr elsif( cursor_point == 12) if( str[cursor_point-1].ord > '1'.ord ) str[cursor_point] = '3' else str[cursor_point] = '9' end elsif( cursor_point == 15) str[cursor_point] = '9' elsif( cursor_point == 11) if( str[cursor_point+1].ord > '3'.ord ) str[cursor_point] = '1' else str[cursor_point] = '2' end else str[cursor_point] = '5' end @str2=str end #puts (@str2) # HH:MM - HH:MM #012345678901234 end def left() #puts '-------------------------------------------------------------------------too left' if((@cursor_point == 31) || (@cursor_point == 28)) @cursor_point -= 1 elsif(@cursor_point == 20) @cursor_point = 31 elsif(@cursor_point == 30) @cursor_point -= 2 elsif(@cursor_point == 27) @cursor_point -= 7 end end def right() #puts '------------------------------------------------------------------------- too right' if((@cursor_point == 30) || (@cursor_point == 27)) @cursor_point += 1 elsif(@cursor_point == 31) @cursor_point = 20 elsif(@cursor_point == 28) @cursor_point += 2 elsif(@cursor_point == 20) @cursor_point += 7 end end def get_value #puts '------------------------------------------------------------------------- too get_value' ret = "n/a" if(@selectMenuIdx != nil) ret = @env.get_candidate2('time_ofoperation.enable')[@selectMenuIdx] end ret end def get_view() #puts '------------------------------------------------------------------------- too get_view' hLine1 = {:align=>:left,:id => @str1} hLine2 = {:align=>:left, :id => @str2, :cursor => (@cursor_point)} disc = [hLine1, hLine2] end end class MenuNodeEnvPirMode < MenuNodeEnv include EventSource def get_return @env.save_env('pir_mode', @selectMenuIdx) #puts "===============================too get_return" super end def get_return2 menu = self #menu end def read_time_offon(idx) #puts '-------------------------------------------------------------------------too read time' if(idx == 0) str=@env.get_env('time_ofoperation.off_on') else str=@env.get_env('time_ofoperation.time') end str1=str[@selected_days_idx] if str != nil str1=str1.split('/') str1=str1[@selected_block_idx] if str1 != nil str1 end def check_time() ret = false entered_time = @str2[11..15] str=@env.get_env('time_ofoperation.time') str1=str[@selected_days_idx] str2=str1.split('/') prev_time='00:00' next_time='23:59' if(@selected_block_idx > 0) prev_time = str2[@selected_block_idx - 1] end if(@selected_block_idx < 3) next_time = str2[@selected_block_idx + 1] end if( (entered_time < next_time) & (entered_time > prev_time)) ret = true end #puts("============ prev_time=#{prev_time} time=#{entered_time} next_time=#{next_time} return=#{ret}") ret end def read_values() #puts '-------------------------------------------------------------------------too read values' id="blk#{@selected_block_idx}" str2=get_desc(id) @str1="#{get_desc("days")}: #{get_desc(@env.get_candidate2('time_ofoperation.days')[@selected_days_idx])} #{str2}" if(read_time_offon(0) == '0') str1=get_desc("off") @selected_days_onoff_idx = 0 else str1=get_desc("on") str1="#{str1} " @selected_days_onoff_idx = 1 end str2= read_time_offon(1) @str2="#{get_desc('cam')} #{str1} #{str2}" #puts "@str1=#{@str1}" #puts "@str2=#{@str2}" end def initialvalue #puts '------------------------------------------------------------------------- too initial value' @selectMenuIdx = @env.get_selected_idx(get_id()) @line = 2 @selected_days_idx=0 @selected_block_idx=0 read_values() res = {:menu=>self, :result=>nil} @cursor_point = 4+16 res end def initialize(id, parents, env, *param, &callback) #puts '-------------------------------------------------------------------------too initialize' super(id, parents, param, callback) @env = env @selected_days_idx=0 @selected_block_idx=0 @selected_days_onoff_idx=0 @selectMenuIdx = @env.get_selected_idx('pir_mode') end def set_idx(idx = 3) @selectMenuIdx = idx @env.save_env('pir_mode', idx) end def get_idx() #puts '-------------------------------------------------------------------------too get_idx' @selectMenuIdx end def execute(mainFlag = false ) #puts '------------------------------------------------------------------------- too execute' exit_flag = false if(mainFlag) res = {:menu=>get_return(), :result=>"saved"} @env.save_env('pir_mode', @selectMenuIdx) pmode=@selectMenuIdx & 0xff if(@selectMenuIdx > 2) if(@selectMenuIdx > 3) pmode = 0x10 else pmode = 0x04 end end ret = {} ret[:mode] = pmode notify('menu/pir_mode', ret) callback() res else save_flag = false offon=read_time_offon(0).to_i time=read_time_offon(1) if(offon != @selected_days_onoff_idx) save_flag = true #puts '-----------------------on/off changed so save it' str=@env.get_env('time_ofoperation.off_on') if(@selected_days_onoff_idx ==0) str[@selected_days_idx][@selected_block_idx*2] = '0' else str[@selected_days_idx][@selected_block_idx*2] = '1' end @env.save_env_val('time_ofoperation.off_on',str) #puts("-----------------------------------new operation offon=#{str}") end if(time != @str2[11..15]) if(check_time() == true) save_flag = true #puts '-----------------------time changed so save it' str=@env.get_env('time_ofoperation.time') str[@selected_days_idx] [@selected_block_idx*6..(@selected_block_idx*6)+4]= @str2[11..15] @env.save_env_val('time_ofoperation.time',str) #puts("-----------------------------------new operation time =#{str}") end end if(save_flag == true) ret = get_msg_val end if(@selected_block_idx < 3) @selected_block_idx +=1 else @selected_block_idx = 0 if( @selected_days_idx < 2) @selected_days_idx +=1 else @selected_days_idx = 0 exit_flag = true end end read_values() if(save_flag == true) notify('menu/time_ofoperation', ret) if exit_flag res = {:menu=>get_return(), :result=>"saved"} else res = {:menu=>get_return2(), :result=>"saved"} end res elsif exit_flag res = {:menu=>get_return(), :result=>"saved"} res end end end def get_msg_val ret = {} ret[:days_id] = @selected_days_idx ret[:blk_id] = @selected_block_idx ret[:off_on] = @selected_days_onoff_idx h10 = ((@str2[11].to_i ) << 4) & 0xf0 h1 = @str2[12].to_i & 0x0f hr = h10 | h1 m10 = ((@str2[14].to_i) << 4 ) & 0xf0 m1 = @str2[15].to_i & 0x0f min = m10 | m1 ret[:hr] = hr ret[:min] = min ret end def up_main() if (@selectMenuIdx != nil) childCount = @env.get_candidate_count(get_id()) - 1 if(0 < @selectMenuIdx) @selectMenuIdx = @selectMenuIdx - 1 else @selectMenuIdx = childCount end end end def down_main() if (@selectMenuIdx != nil) childCount = @env.get_candidate_count(get_id()) - 1 if(childCount > @selectMenuIdx) @selectMenuIdx = @selectMenuIdx + 1 else @selectMenuIdx = 0 end end end def up() #puts '------------------------------------------------------------------------- too up' #puts "up function" cursor_point = @cursor_point - 16 str = @str2 if( cursor_point == 4) if(@selected_days_onoff_idx == 0) @selected_days_onoff_idx = 1 @str2[4..6] = "#{get_desc("on")} " else @selected_days_onoff_idx = 0 @str2[4..6] = get_desc("off") end #read_values() else if (cursor_point == 12) if( str[cursor_point-1].ord > '1'.ord ) str = increment_1(2, cursor_point, 3) else str = increment_1(2, cursor_point, 9) end elsif( cursor_point == 11) if( str[cursor_point+1].ord > '3'.ord ) str = increment_1(2, cursor_point, 1) else str = increment_1(2, cursor_point, 2) end elsif( cursor_point == 15 ) str = increment_1(2, cursor_point, 9) elsif(cursor_point == 14) str = increment_1(2, cursor_point, 5) #else end @str2=str end #puts (@str2) # HH:MM - HH:MM #012345678901234 end def down() #puts '------------------------------------------------------------------------- too down' #puts "down function" cursor_point = @cursor_point - 16 str = @str2 if( cursor_point == 4) if(@selected_days_onoff_idx == 0) @selected_days_onoff_idx = 1 @str2[4..6] = "#{get_desc("on")} " else @selected_days_onoff_idx = 0 @str2[4..6] = get_desc("off") end #read_values() else if( str[cursor_point].ord > '0'.ord ) str[cursor_point] = (str[cursor_point].ord - 1).chr elsif( cursor_point == 12) if( str[cursor_point-1].ord > '1'.ord ) str[cursor_point] = '3' else str[cursor_point] = '9' end elsif( cursor_point == 15) str[cursor_point] = '9' elsif( cursor_point == 11) if( str[cursor_point+1].ord > '3'.ord ) str[cursor_point] = '1' else str[cursor_point] = '2' end else str[cursor_point] = '5' end @str2=str end #puts (@str2) # HH:MM - HH:MM #012345678901234 end def left() #puts '-------------------------------------------------------------------------too left' if((@cursor_point == 31) || (@cursor_point == 28)) @cursor_point -= 1 elsif(@cursor_point == 20) @cursor_point = 31 elsif(@cursor_point == 30) @cursor_point -= 2 elsif(@cursor_point == 27) @cursor_point -= 7 end end def right() #puts '------------------------------------------------------------------------- too right' if((@cursor_point == 30) || (@cursor_point == 27)) @cursor_point += 1 elsif(@cursor_point == 31) @cursor_point = 20 elsif(@cursor_point == 28) @cursor_point += 2 elsif(@cursor_point == 20) @cursor_point += 7 end end def get_value #puts '------------------------------------------------------------------------- too get_value' ret = "n/a" if(@selectMenuIdx != nil) ret = @env.get_candidate(get_id())[@selectMenuIdx] end ret end def get_view() #puts '------------------------------------------------------------------------- too get_view' hLine1 = {:align=>:left,:id => @str1} hLine2 = {:align=>:left, :id => @str2, :cursor => (@cursor_point)} disc = [hLine1, hLine2] end end class MenuNodeEnvSaveAsc < MenuNodeEnv def execute( ) @env.save_env_val(get_id(), @cursor_str_buff[1..@cursor_str_buff.length - 1]) res = {:menu=>get_return(), :result=>"saved"} @selectMenuIdx = 0; callback() res end def initialvalue val = @env.get_env_value(get_id()) if(val != nil) @cursor_str_buff = " " + val @cursor_point = @cursor_str_buff.length - 1 res = {:menu=>self, :result=>nil} else res = {:menu=>get_return(), :result=>"n/a"} end end def get_view() hLine1 = {:align=>:center,:id => get_id()} hLine2 = {:align=>:left, :id => @cursor_str_buff, :cursor => @cursor_point + 16} disc = [hLine1, hLine2] end def down() #if( @cursor_str_buff[@cursor_point] == ' ' ) # @cursor_str_buff[@cursor_point] = '9' #elsif( @cursor_str_buff[@cursor_point] == 'A' ) # @cursor_str_buff[@cursor_point] = ' ' #elsif( @cursor_str_buff[@cursor_point] == '.' ) # @cursor_str_buff[@cursor_point] = 'z' #elsif( @cursor_str_buff[@cursor_point] == 'a' ) # @cursor_str_buff[@cursor_point] = 'Z' if( @cursor_str_buff[@cursor_point] == ' ' ) @cursor_str_buff[@cursor_point] = '~' else @cursor_str_buff[@cursor_point] = (@cursor_str_buff[@cursor_point].ord - 1).chr end end def up() #if( @cursor_str_buff[@cursor_point] == ' ' ) # @cursor_str_buff[@cursor_point] = 'A' #elsif( @cursor_str_buff[@cursor_point] == 'Z' ) # @cursor_str_buff[@cursor_point] = 'a' #elsif( @cursor_str_buff[@cursor_point] == 'z' ) # @cursor_str_buff[@cursor_point] = '.' #elsif( @cursor_str_buff[@cursor_point] == '9' ) # @cursor_str_buff[@cursor_point] = ' ' if( @cursor_str_buff[@cursor_point] == '~' ) @cursor_str_buff[@cursor_point] = ' ' else @cursor_str_buff[@cursor_point] = (@cursor_str_buff[@cursor_point].ord + 1).chr end end def left() if(1 < @cursor_point) @cursor_str_buff.chop! @cursor_point -= 1 else #@cursor_str_buff = " " end end def right() if(13 > @cursor_point) @cursor_point += 1 @cursor_str_buff.concat " " end end end class MenuNodeFormat < MenuNode def execute( ) if(@format == true) super() res = {:menu=>get_return(), :result=>"Done"} else res = {:menu=>get_return(), :result=>nil} end res end def initialvalue @format = false super() end def up() @format = !@format end def down() up() end #01234567890123456 # NO def get_view() hLine1 = {:align=>:left,:id =>"CONFIRM FORMAT",} if(@format == false) cursor = 7 + 16 hLine2 = {:align=>:center, :id =>"no", :cursor=>cursor} else cursor = 6 + 16 hLine2 = {:align=>:center, :id =>"yes", :cursor=>cursor} end disc = [hLine1, hLine2] end end class MenuNodeDefault < MenuNode def execute( ) if(@default == true) super() res = {:menu=>get_return(), :result=>"Done"} else res = {:menu=>get_return(), :result=>nil} end res end def initialvalue @default = false super() end def up() @default = !@default end def down() up() end #01234567890123456 # NO def get_view() hLine1 = {:align=>:left,:id =>"RESTORE SETTINGS",} if(@default == false) str1 = "TO DEFAULT: NO " else str1 = "TO DEFAULT: YES" end cursor = 12 + 16 hLine2 = {:align=>:left, :id => str1, :cursor=>cursor} disc = [hLine1, hLine2] end end class MenuNodeSendTestImage < MenuNode def execute( ) if(@default == true) super() res = {:menu=>get_return(), :result=>nil} else res = {:menu=>get_return(), :result=>nil} end res end def initialvalue @default = false super() end def up() @default = !@default end def down() up() end #01234567890123456 # NO def get_view() hLine1 = {:align=>:left,:id =>"CONFIRM SEND OF ",} if(@default == false) str1 = "TEST IMAGE: NO " else str1 = "TEST IMAGE: YES" end cursor = 12 + 16 hLine2 = {:align=>:left, :id => str1, :cursor=>cursor} disc = [hLine1, hLine2] end end class MenuNodeTree < MenuNode def execute( ) res = get_child()[@selectMenuIdx].initialvalue(); super() res end def up() childCount = get_child().count - 1 if(0 < @selectMenuIdx) @selectMenuIdx = @selectMenuIdx - 1 else @selectMenuIdx = childCount end end def down() childCount = get_child().count - 1 if(childCount > @selectMenuIdx) @selectMenuIdx = @selectMenuIdx + 1 else @selectMenuIdx = 0 end end def get_view() hLine1 = {:align=>:center,:id => get_id()} hLine2 = {:align=>:left, :id => get_child()[@selectMenuIdx].get_id()} disc = [hLine1, hLine2] end end class MenuNodeFileTree < MenuNode def initialize(id, parents, path, *param, &callback) @path = path super(id, parents, param, callback) end def execute( ) if(@callback != nil) @callback.call(@file[@selectMenuIdx]) end end def initialvalue @file = Dir[@path] if(@file.size != 0) @file.sort! res = {:menu=>self, :result=>nil} else res = {:menu=>get_return(), :result=>"File Missing"} end @selectMenuIdx = 0 res end def up() childCount = @file.size - 1 if(0 < @selectMenuIdx) @selectMenuIdx = @selectMenuIdx - 1 else @selectMenuIdx = childCount end end def down() childCount = @file.size - 1 if(childCount > @selectMenuIdx) @selectMenuIdx = @selectMenuIdx + 1 else @selectMenuIdx = 0 end end def get_view() name = @file[@selectMenuIdx].split('-') hLine1 = {:align=>:center,:id => get_id()} hLine2 = {:addNum=>@selectMenuIdx, :align=>:left, :id => name[name.size - 1]} disc = [hLine1, hLine2] end end class MenuNodeCallback < MenuNode def initialvalue callback() res = {:menu=>get_return(), :result=>"Done"} end end class MenuNodeCallbackOnExecute < MenuNode def execute() res = {:menu=>get_return(), :result=>"Done"} super() res end end class Menu def initialize(env, menuL0) @env = env @menuL0 = menuL0 @currentMenu = @menuL0 end def clear() @currentMenu = @menuL0 @currentMenu.initialvalue() end def execute(key) res = @currentMenu.execute() @currentMenu = res[:menu] res[:result] end def escape(key) if(key == "Menu") ret = true if(@currentMenu == @menuL0) ret = false else @currentMenu = @currentMenu.get_return() end ret end end def key_input(key) if(key == 'Down') @currentMenu.down() elsif(key == 'Up') @currentMenu.up() elsif(key == 'Left') #@currentMenu = @currentMenu.left() @currentMenu.left() elsif(key == 'Right') #@currentMenu = @currentMenu.right() @currentMenu.right() end end def get_view() if @currentMenu != nil @currentMenu.get_view() end end def get_time() Time.now.strftime(' %d/%m/%y %H:%M') end end # Test code... if $0 == __FILE__ l0 = MenuNode.new(nil, "root") l1 = MenuNode.new(l0, "config1") l2 = MenuNode.new(l1, "op1") l2 = MenuNode.new(l1, "op2") l2 = MenuNode.new(l1, "op3") l2 = MenuNode.new(l1, "op4") l1 = MenuNode.new(l0, "config2") l2 = MenuNode.new(l1, "op1") l2 = MenuNode.new(l1, "op2") l2 = MenuNode.new(l1, "op3") l2 = MenuNode.new(l1, "op4") current = l0.root puts(current.name) current = current.child[0] puts(current.child[0].name) puts(current.child[1].name) puts(current.child[2].name) puts(current.child[3].name) puts("done") puts("done") end opt/wtc2.0/src/setup_ppp00000755000175200017520000000057413557057144015750 0ustar bushnellbushnell#!/bin/sh mkdir -p /etc/ppp/peers port="$1" apn="$2" echo $port echo $apn cp /opt/wtc2.0/src/ppp_scripts/q* /etc/ppp/peers/ sed -i "s/config_var_port/$port/g" /etc/ppp/peers/quectel-ppp sed -i "s/config_var_apn/$apn/g" /etc/ppp/peers/quectel-chat-connect #ruby -I . -I ../lib upload_photo.rb -c wtc2_config_v0.0.1-a.yaml -p ./test/lte_tests/thumbs/number8.jpg -n ATT opt/wtc2.0/src/boardtest.rb0000644000175200017520000020316713557057144016242 0ustar bushnellbushnell#!/usr/bin/ruby # The following is an instruction to rdoc. It specifies the main page for the documentation. # This directive must appear in a .rb file. We placed it here because this is the main # control of the application. # :main: README.txt $LOAD_PATH.push File.expand_path("..", __FILE__) $video_recording = false $final_test_flag = false $final_test_finished_flag = false $imei_iccid_valid = false $imei= nil $iccid= nil $imsi= nil $version_m0 = "" $menu_values_changed = false $lastupdatetime = "1970-01-01T12:00:00" $developer_mode = false $networkname ="" $qtel_firmware = nil $testserver = nil $gps_wakeup_flag = false $firmware_ver = nil #$power_reset_cntr = 0 $ip_failed_cntr = 0 $camera_timezone="+0" $wifi_timeout=600 #time after which the wifi will shut down $tracking_enabled_oncamera = false require 'yaml' require 'json' require 'optparse' require 'syslog/logger' require 'utils' require 'menu' require 'view' require 'timer' require 'comm' require 'env' require 'work_que' #require 'nmea' require 'camera' require 'keypad' require 'picture_manager' require "monitor" require "connection_manager" require 'version' require 'gpio' require 'mqtt' require 'debug' Thread.abort_on_exception = true # This is the central control for the WTC2.0 application. Control is responsible for all # operations and performs them with the help of other classes and processes. class Control SLEEP_GUARD_TIME = 3 PICTURE_BURST_TIME = 1 MAX_SERVER_SNED_QUE = 1 MAX_CAP_QUE = 10 MAX_NETWORK_TRY_COUNT = 1 # max no of times, network will be checked on resume #possible states of the modem MODEM_REBOOT = 0 # modem will not work wihout a reboot of quectel modem, should sleep MODEM_OFF = 1 # covers suspended and low power mode sleep and fails, can sleep MODEM_CONNECTING = 2 # in the process of switching on and dialing ppp, cannot sleep MODEM_PORTS_AVAILABLE = 3 # can talk to A83, but no network as yet MODEM_CONNECTED = 4 # got ip and wating for job, cannot sleep MODEM_STARTING_UPLOAD = 5 # starting upload or in the midst of it, cannot sleep MODEM_FINISHED_UPLOAD = 6 # complted upload , cannot sleep until no more uploads / downloads MODEM_IDLE = 7 # all work done can go to sleep:103 #GPS STATES GPS_ABORTED = 0 GPS_SWITCHED_OFF = 1 GPS_STARTED = 2 GPS_FINDING_FIX = 3 GPS_FIXED = 4 #Abort timings NO_GPS_DATA_TIME = 180 GPS_DATA_TIME = 60 THEFT_MODE_TIME = 90 #GPS try count GPS_TRY_COUNT = 3 UPLOAD_BATCH_SIZE = 20 #No of photos that can load in one wakeup COLD_BOOT = 0 RESUME_WAKEUP = 1 STREAMING_OFF = 0 STREAMING_ON = 1 include EventListener @log = nil # params: # - config: This is the contents of the application configuration file. See config.yaml for details. def initialize(config={}) #@@counter += 1 puts "???????????????????????? initialuze main ?????????????????????????????????????" #system(%Q(/opt/wtc2.0/src/sleep.sh)) #sleep(2) #system(%Q(modprobe -v 8723bs)) #sleep(0.2) #system(%Q(/opt/wtc2.0/src/enablehotspot.sh)) #sleep(0.2) @config = config @keypad = nil @log = Syslog::Logger.new(@config.control.log_name) @set_field_scan_flag=true @take_picture_in_process=false @remaining_pictures_no=0 # Network Variables @modem=nil @quectelcmds=nil @thread_photo = nil @thread_modem = nil @thread_gps = nil @imei=@iccid=@rssi="0" @networkstate=0 #0 not available, 1 available @modemstate=0 #0 not enabled, 1 enabled @modem_state = MODEM_OFF @modem_sleep_run = true @upload_photo_count=0 @upload_photo_count_copy=0 @update_view_flag = true @triedconnecting=0 @sdcard_status = false @disk_space = {:free=>0, :total=>0} @version = Version.new() @modemstarttime = nil @photocell_change_req_count = 0 @hotspot = 0 @hotspotactivated = 0 @sleep_con_check=0 @startmode = COLD_BOOT @streaming = STREAMING_OFF @sleep_count = 0 @isMenuDirty = false @wakeupcounter = 0 #count the number of wakeups in this session @read_bat_counter = 0 @gps_state = GPS_SWITCHED_OFF @image_to_network_try = 0 @latitude = @longitude = @satellite = @gps_errcode =0 @cut_off_time = NO_GPS_DATA_TIME @accessgpstate = Mutex.new @dailycheckin = true # TO DO set to false once daily timer is enabled @storageused = @storagesize = 0 # Load Environment setting file and International Language descript @start_cursor = false @start_elapsed = true @pressed_times = 0 @next_test = false @modemFound = 0 @keypressed = nil @key_result = nil @testcount = 0 @errcode="" @pircount=0 @satNo = 0 @elapsed_time = 0 @accesscontrol = Mutex.new @test_result = ["XXXXXXXXXXXXXXX "," "] @timer_cursor = Timer.new('never', method(:cursor_routine), false) @timer_elapsed = Timer.new('never', method(:elapsed_routine), false) @cursor_row = 0 @cursor_pos = 0 @cursor_toggle = false @env = Env.new(config.def_env) @location_available = false @camera = CameraControl.new(@config.camctrl, @env) @view = View.new(@config, @env, test_menu(), @camera) @view.displayDiret("Board Test V2.14", 1, :left) @view.displayDiret("Loading.. ", 2, :left) #@view = View.new(@config, @env, initial_menu()) @turn_on_display_flag = false #updatePhotoUploadCount #@view = View.new(@config, @env, MenuNodeTree.new("setup", nil)) # Instantiate all objects #@view = Display.new(@config.lcdctrl, desc) @wq_cap = WorkQueue.new 1, MAX_CAP_QUE #@wq_send = WorkQueue.new MAX_SERVER_SNED_QUE, MAX_SERVER_SNED_QUE #ask #@mqtt_th = Thread.new{ getMqttMessages } #ask # We will listen to camera events @comm = Comm.new(@config.m0ctrl, [[0x02,@env.get_env_value('Set_photocell')],[0x06,@env.get_env_value('imaage_interval')], [0x0c,@env.get_env_value('capture_mode'), @env.get_env_value('movie_length')] ]) @version_m0 = @comm.get_mo_revision() Log4Ienso.log.P_NOTICE("=================== @version_m0=#{@version_m0 } ======") # Listent to keypad events @keypad = Keypad.new(@config.keypadctrl) @picman = PictureManager.new(@config.picman) ConnectionManager.setConnectionParameters(@env.get_env_value('Select_Network'),@config) @thread_modem = Thread.new { startModemandNetwork(@env.get_env_value('Select_Network'),COLD_BOOT) } #@thread_photo = Thread.new { sendPhotos } #startModem(@env.get_env_value('Select_Network'),COLD_BOOT) sleep(1) Log4Ienso.log.P_NOTICE("env value is #{@env.get_env('switch_on/off_gps')}") if @connmanager != nil && @location_available == false @thread_gps = Thread.new { getGPSLocation } end #@nmea = Nmea.new(config.camctrl.gps.tty); #ask @mutex_sleep = Mutex.new @timer_lcd_off = Timer.new(@env.get_env_value('lcd_off_time')) @timer_sleep_guard = Timer.new(SLEEP_GUARD_TIME) @timer_picture_burst = Timer.new(PICTURE_BURST_TIME) #@timer_imagetest = Timer.new('never', method(:check_send_image_to_network), false) @picman.add_listener(@view) @picman.add_listener(self) @keypad.add_listener(self) @keypad.add_listener(@view) @camera.add_listener(self) #@debug_pin = Gpio.new(123) #@debug_pin.direction='out' #@debug_pin.clear #cameera_set_change() puts("communicating with M0") puts("M0 OK") @comm.add_listener(self) @comm.interrupt_mask(false) #camera_get_set_day_night() @comm.interrupt_mask(false) #@picman.start() #initial_M0() sleep(1) @satcount = 0 #@gpsth = Thread.new{ runGPS } end def is_numeric?(obj) obj.to_s.match(/\A[+-]?\d+?(\.\d+)?\Z/) == nil ? false : true end def getGPSLocation puts("?????????------------ Starting GPS loop with modem state -------------------" + @modem_state.to_s) rval=0 loop do puts("????????? in gps loop .. modem is #{@modem_state} and GPS #{@gps_state}") if (@modem_state >= MODEM_PORTS_AVAILABLE && @gps_state > GPS_ABORTED && @gps_state < GPS_FIXED ) puts("????????? starting gps .............................. #{@modem_state} and GPS #{@gps_state}") if @gps_state == GPS_SWITCHED_OFF puts("????????? Setting up GPS") @connmanager.SetIsGPSSessionActive(true) rval = @connmanager.enableGPS() if rval.strip == "504" # gps session is active @accessgpstate.lock @gps_state = GPS_STARTED @accessgpstate.unlock puts("????????? GPS STARTED") @connmanager.setGPSState(@gps_state) end end puts("????????? GPS state is #{@gps_state}") if @gps_state == GPS_STARTED || @gps_state == GPS_FINDING_FIX #@latitude, @longitude, errcode = @connmanager.getGPSData() #Log4Ienso.log.P_INFO("Lat:#{@latitude} Lng:#{@longitude} ") satNO, errcode = @connmanager.getGPSData2() puts("????????? ------------- satNo=#{satNO}, errcode=#{errcode}") if (errcode == "FAIL") || (satNO ==0) puts("????????? GPS sat no failed so retry") @accessgpstate.lock @gps_state = GPS_FINDING_FIX @accessgpstate.unlock #@connmanager.setGPSState(0) #@connmanager.SetIsGPSSessionActive(false) #@connmanager.shutdownModem sleep(4) next end @gps_state = GPS_FINDING_FIX @satNo = satNO @accessgpstate.lock @gps_state = GPS_FIXED @accessgpstate.unlock @location_available = true @connmanager.setGPSState(0) #let @connmanager.SetIsGPSSessionActive(false) break end end sleep 6 Thread.pass end @connmanager.stopGPS() Log4Ienso.log.P_NOTICE("<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>") end # sendPhotos executed in a thread def sendPhotos batch = 0 localtime = Time.now loop do #puts("sleep value is " + @env.get_env('wirless_on/off') ) if(@env.get_env('wirless_on/off') == 'off') if ( @modem_state == MODEM_IDLE || @modem_state >= MODEM_CONNECTED) #there is nothing to do lets sleep @connmanager.startModemSleepNormal break end end #Log4Ienso.log.P_NOTICE("Modem state is #{@modem_state}") if (@modem_state >= MODEM_CONNECTED && @modem_state < MODEM_IDLE ) Log4Ienso.log.P_INFO("CONNECTED TO MODEM...") thumb = nil if batch < UPLOAD_BATCH_SIZE thumb = @picman.get_thumb_for_send_server() batch+=1 end if thumb == nil && ( @modem_state == MODEM_FINISHED_UPLOAD || @modem_state == MODEM_IDLE || @modem_state == MODEM_CONNECTED) #there is nothing to do lets sleep @connmanager.startModemSleepNormal break end if thumb != nil @th = Thread.new { send_thumb_to_server(thumb) } end @connmanager.updateNetworkState #check if network is still there end timediff = (Time.now - localtime).abs if ( @modem_state == MODEM_REBOOT && @triedconnecting == 1 || timediff > 90 ) Log4Ienso.log.P_NOTICE("Aborting uploading") @connmanager.startModemSleepNormal break end sleep 0.1 end Log4Ienso.log.P_INFO("sendPhotos finish") end # executed in a thread def startModemandNetwork(networkname,starttype) count=1 @modemstarttime = Time.now Log4Ienso.log.P_CLEAN("///////// ---------------------------- Starting Modem Loop ---------------------------\n") loop do if @modem_state == MODEM_OFF || @modem_state == MODEM_CONNECTING #@modem_state = MODEM_CONNECTING if @connmanager == nil @connmanager = ConnectionManager.new(@config) @connmanager.add_listener(self) @triedconnecting = 1 #attempt made to connect to the network end status = @connmanager.startNetworkConnectionBoardTest(starttype,@wakeupcounter) @imei,@iccid = @connmanager.getIMEIandICCIDForMenu Log4Ienso.log.P_MAGENTA("///////// In control with @imei=#{@imei} and @iccid=#{@iccid} and status=#{status}") system(%Q(/opt/wtc2.0/src/modemtime.sh)) sleep(0.5) if status == 0 #@rssi = @connmanager.getRSSI(1) #puts("/////////>>> Setting modem state to modem connected with RSSI #{@rssi} ") if starttype != COLD_BOOT && @dailycheckin == true @connmanager.cameraStatusSetandUpdate(@storageused,@storagesize,@battery,@latitude,@longitude,@rssi) end @modem_state = MODEM_CONNECTED while (@gps_state < GPS_FINDING_FIX) sleep(1) end break end count+=1 sleep (2) if count > MAX_NETWORK_TRY_COUNT || status == 5 || @iccid == "" puts("///////// Aborting network connection opening") Log4Ienso.log.P_INFO("NO sim card.....") if @iccid == nil @imei,@iccid = @connmanager.getIMEIandICCIDForMenu puts("///////// In control (abort) with #{@imei} and #{@iccid}") @thread_photo.kill if @thread_photo !=nil #@connmanager.startModemSleepNormal break end end sleep(0.1) end Log4Ienso.log.P_NOTICE("????????????????<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>????????????????") end def sd_card_mounted?() # the regex comparison (=~) returns the location of the match (positive # integer) or nil if there is not match not (`mount` =~ %r{/media/photos}).nil? end def camera_change_ir_led() val = 1 val = @comm.get_day_night() if @comm != nil if(val == 0) level = @env.get_env_value('led_power') Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} set night IR LED level to#{level} ") @camera.set_ir_led_power(level) if @camera != nil end end def camera_get_set_day_night() val = 1 val = @comm.get_day_night() if @comm != nil if(val == 0) @camera.set_night if @camera != nil @view.set_day_and_night('night') if @view != nil else @camera.set_day if @camera != nil @view.set_day_and_night('day') if @view != nil end end def cameera_set_change(reason = {:day => false, :night => false}) if(reason[:photocell]) photocell = @comm.get_photocell() @photocell_change_req_count +=1 @camera.light_lvl_change Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} Photocell changed #{photocell} count #{@photocell_change_req_count}") end if(reason[:day] == true) Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} reason = day, camera changed to day ") @camera.set_day @view.set_day_and_night('day') elsif(reason[:night] == true) Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} reason = night, camera changed to night ") @camera.set_night @view.set_day_and_night('night') else Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} get day or night from M0 and set camera based on it ") camera_get_set_day_night() end end def makejson() exifTag = Hash.new() exifTag[:Make] = "IENSO" exifTag[:Model] = "WTC2.0" exifTag[:ImageDescription] ={:ifdType => 1, :tagId => 270,:tagType =>2 , :value => @comm.get_photocell().to_s }; #for save Photocell value exifTag[:Software] ={:ifdType => 1, :tagId => 305,:tagType =>2 , :value => @version.get_version() }; #for save Software version #exifTag[:Software] ={:ifdType => 1, :tagId => 305,:tagType =>2 , :value => {:Versions => {:A => @version.get_version() , :M => @version_m0}} }; #for save Software version #exifTag[:DateTimeOriginal] = Time.now.strftime("%Y:%m:%d %H:%M:%S") #@nmea.dateTime exifTag[:DateTimeOriginal] = Time.now.strftime('%Y-%m-%dT%H:%M:%S') #@nmea.dateTime latitude = str_to_latitude(@env.get_env_value('latitude')) longitude = str_to_longitude(@env.get_env_value('longitude')) exifTag[:GPSLatitude] = [latitude[:degree], latitude[:minute], latitude[:second]] exifTag[:GPSLatitudeRef] = latitude[:azimuth] exifTag[:GPSLongitude] = [longitude[:degree], longitude[:minute], longitude[:second]] exifTag[:GPSLongitudeRef] = longitude[:azimuth] exifTag[:ExposureTime] = {:ifdType => 3, :tagId => 33434,:tagType =>5 , :value => [@camera.get_exposure()] } exifTag[:DocumentName] = {:ifdType => 1, :tagId => 269,:tagType =>2 , :value => "Gain:#{@camera.get_gain()}" } # it's Example how to insert unsupported Tag # typedef enum { # IFD_UNKNOWN = 0, # IFD_0TH, # IFD_1ST, # IFD_EXIF, # IFD_GPS, # IFD_IO # } IFD_TYPE; # typedef enum { # TYPE_BYTE = 1, # TYPE_ASCII, # TYPE_SHORT, # TYPE_LONG, # TYPE_RATIONAL, # TYPE_SBYTE, # TYPE_UNDEFINED, # TYPE_SSHORT, # TYPE_SLONG, # TYPE_SRATIONAL # } IFD_TAG_TYPE; # exifTag[:DateTime] = {:ifdType => 1, :tagId => 132,:tagType =>2 , :value => @nmea.dateTime }; JSON.generate(exifTag) end def test_menu menuL0 = MenuNodeSetup.new("menu", nil) l1 = MenuNodeSub.new("setup", menuL0) l2 = MenuNodeTree.new("developer", l1) l3 = MenuNodeTree.new("config", l2) l4 = MenuNodeEnv.new("lcd_off_time",l3, @env){ @timer_lcd_off.start(false, @env.get_env_value('lcd_off_time')) } l3 = MenuNodeTree.new("take_pic", l2) l4 = MenuNodeCallback.new("take_pic_day", l3){ @wq_cap.enqueue_p(method(:take_picture),false, 1, :day); @wq_cap.join } menuL0 end def set_image_type() @camera.set_image_vid_resolution(@env.get_env_value('capture_mode')) if(@env.get_env_value('capture_mode') == 'image') length = @env.get_env_value('capture_count') else length = @env.get_env_value('movie_length') end @comm.set_image_type(@env.get_env_value('capture_mode'), length) end def set_pir_mode_timer() if( @env.get_env_value('pir_mode') == 'timer') idx = 4 packet=[0x0e, idx & 0xff] ret=@comm.set_m0_pir_mode(packet) end end def set_m0_time_zone() off_ons =@env.get_env('time_ofoperation.off_on'); times = @env.get_env('time_ofoperation.time'); off_ons.each_with_index do |off_on , days_idx| time = times[days_idx].split('/') off_on = off_on.split('/') off_on.each_with_index do | offon, blk_idx | time2 = time[blk_idx].split(':') Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} days=#{days_idx} block=#{blk_idx} offon=#{offon} hr=#{time2[0]} min=#{time2[1]} " ) packet=[0x0d, days_idx & 0xff, blk_idx & 0xff, offon.to_i & 0xff, time2[0].to_i & 0xff, time2[1].to_i & 0xff] ret=@comm.set_m0_time_zone(packet) end end end def initial_M0() @comm.set_photocell(@env.get_env_value('Set_photocell')) @comm.set_picdelaytime(@env.get_env_value('imaage_interval')) ret=set_m0_time_zone() set_field_scan() set_image_type() set_pir_mode() @comm.set_pir_sensitivity(@env.get_selected_idx('pir')) if @comm != nil end def set_pir_mode() idx = @env.get_selected_idx('pir_mode') if(idx > 2 ) if(idx > 3) idx = 16 else idx = 4 end end packet=[0x0e, idx & 0xff] ret=@comm.set_m0_pir_mode(packet) end def reset_default @env.reset_default() if @env != nil @comm.set_default_settings() if @comm != nil @isMenuDirty = true end def send_image_to_network enter_special_func(); if(@env.get_env('wirless_on/off') == 'off') @view.displayDiret("TURN WIRELESS ON", 1, :left) @view.displayDiret("AND RE-TRY .. ", 2, :left) Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} ....wireless is off ,turn it on and retry....") sleep(3) exit_special_func() return end @thread_modem = Thread.new { startModemandNetwork(@env.get_env_value('Select_Network'),RESUME_WAKEUP) } @thread_photo = Thread.new { sendPhotos } @wq_cap.enqueue_p(method(:take_picture), false, 1) #@timer_imagetest.start(false, 6); @image_to_network_try = 0 @upload_photo_count_copy = @upload_photo_count @view.displayDiret("SENDING IMAGE ", 1, :left) @view.displayDiret("PLEASE WAIT... ", 2, :left) Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} ....sending image to network started......") @update_view_flag = false @view.view_update() end def check_send_image_to_network (test) if (@upload_photo_count_copy < @upload_photo_count) @view.displayDiret("SUCCESSFUL... ", 2, :left) Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} ....sending image to network successful......") else if(@image_to_network_try < 5) @image_to_network_try += 1 #try again #@timer_imagetest.start(false, 5); return else @view.displayDiret("FAILED ... ", 2, :left) Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} ....sending image to network failed......") end end sleep(3) @update_view_flag = true exit_special_func(); end def refreshMenu #enter_special_func(); @env = nil @env = Env.new(@config.def_env) @view.refreshMenu(@env,initial_menu()) if @view != nil #exit_special_func() return "refreshed" end def enableHotspot wlan="" if @hotspot == 0 enter_special_func(); if @startmode == COLD_BOOT or @hotspotactivated == 0 puts("starting in cold mode") @hotspotactivated = 1 system("/opt/wtc2.0/src/enablehotspot.sh &") wlan = `ifconfig -a | cut -d" " -f1 | grep w | head -1` if wlan == nil or wlan =="" return "Failed" end system("/usr/bin/ruby -I /opt/wtc2.0/src -I /opt/wtc2.0/lib/ /opt/wtc2.0/src/webserver.rb -o 0.0.0.0 &") elsif @startmode == RESUME_WAKEUP puts("starting in warm mode") `killall hostapd | sh` sleep(4) `modprobe -v 8723bs` sleep(1) #`/usr/sbin/hostapd -B /etc/hostapd.conf & | sh` system("/opt/wtc2.0/src/enablehotspot.sh &") wlan = `ifconfig -a | cut -d" " -f1 | grep w | head -1` if wlan == nil or wlan =="" return "Failed" end system("/usr/bin/ruby -I /opt/wtc2.0/src -I /opt/wtc2.0/lib/ /opt/wtc2.0/src/webserver.rb -o 0.0.0.0 &") end @hotspot = 1 #sleep(0.1) #system("/opt/wtc2.0/src/streamf.sh") end # return ":On " + wlan end def disableHotspot if @hotspot == 1 @hotspot = 0 system("/opt/wtc2.0/src/disablewebserver.sh") #`killall hostapd` if @streaming == STREAMING_ON system("/opt/wtc2.0/src/disablehotspotetstreaming.sh") end exit_special_func() return "Hotspot Off" end end def resetModemValue `rm /var/wtc2.0/lte.config` return "Reboot camera" end def disableTxRx if @connmanager != nil r = @connmanager.stopTxRx return r end return "Modem offline" end def enableTxRx if @connmanager != nil r = @connmanager.startTxRx return r end return "Modem offline" end def startStreaming if @streaming == STREAMING_OFF and @hotspot == 1 system("/opt/wtc2.0/src/streamf.sh") @streaming = STREAMING_ON return "streaming..." else return "hotspot off" if @hotspot=="0" end end def endStreaming if @streaming == STREAMING_ON @hotspot = 0 @streaming = STREAMING_OFF system("/opt/wtc2.0/src/disablehotspotetstreaming.sh") sleep(2) @camera = CameraControl.new(@config.camctrl, @env) exit_special_func() return "Streaming Off" end return "Streaming is off" end def resetUploadCount `echo 0 > /var/wtc2.0/uploadcount.counter` @upload_photo_count = 0 return "Counter reset" end def updatePhotoUploadCount if @startmode == COLD_BOOT if !File.exists?('/var/wtc2.0/uploadcount.counter') `touch /var/wtc2.0/uploadcount.counter` else c = `cat /var/wtc2.0/uploadcount.counter` @upload_photo_count = c.chomp.strip.to_i end else `echo #{@upload_photo_count} > /var/wtc2.0/uploadcount.counter` end end # temporary function required until we need to change sim cards, remove in final version # when sim card is known def updateNetwork(networkname) ConnectionManager.setConnectionParameters(networkname,@config) end def enter_special_func @timer_lcd_off.start(false, 'never') @comm.interrupt_mask(true) end def exit_special_func @comm.interrupt_mask(false) @timer_lcd_off.start(false, @env.get_env_value('lcd_off_time')) end def upgradeFirmware(path) #imgfile = "/media/sd-mmcblk0p1/wtc_sd*.img" #my_dir = Dir[imgfile] #my_dir.sort! {|x,y|y<=>x} #imgfile = my_dir[0] imgfile = path if File.exists?(imgfile) Log4Ienso.log.P_NOTICE("Download #{imgfile}") enter_special_func() @view.displayDiret("A83 Upgrade", 1, :center) @view.displayDiret("copying..", 2, :center) @log.info("Upgrade Firmware Start") system("dd if=#{imgfile} of=/dev/mmcblk1") @log.info("Upgrade Firmware Sync") # system('sync') @log.info("Upgrade Firmware End") loop do @view.displayDiret("SUCCESS", 2, :center) sleep(1) @view.displayDiret(" ", 2, :center) sleep(1) system('sync') end #exit_special_func() else @view.displayDiret("A83M0 Upgrade", 1, :center) @view.displayDiret("Fail", 2, :center) @log.info("Upgrade Firmware Fail") sleep(1) end end def upgradeFirmwareM0(path) #binfile = "/media/sd-mmcblk0p1/wtc_m0*.bin" #binfile = "/media/photos/wtc_m0*.bin" #if File.exists?(binfile) == false # binfile = "/media/sd-mmcblk0p1/wtc_m0*.bin" #end #my_dir = Dir[binfile] #my_dir.sort! {|x,y|y<=>x} #binfile = my_dir[0] #@comm = nil; binfile = path if File.exists?(binfile) @log.info("Upgrade M0 Firmware Start #{binfile}") @view.displayDiret("M0 Upgrade", 1, :center) @view.displayDiret("copying..", 2, :center) enter_special_func() @comm.download_firmware(binfile) @view.displayDiret("SUCCESS", 2, :center) sleep(1) exit_special_func() @log.info("Upgrade M0 Firmware End") else @view.displayDiret("M0 Upgrade", 1, :center) @view.displayDiret("Fail", 2, :center) sleep(1) @log.info("Upgrade M0 Firmware Fail") end #@comm = Comm.new(@config.m0ctrl, [[0x02,@env.get_env_value('Set_photocell')],[0x06,@env.get_env_value('imaage_interval')]]) end # This methods handles events that were generated by EventSource that we registered to. # See new for a list of sources to which we register. def handle_event(event, data = nil) # Camera has finished capturing an image. if event =~ %r{keypad/keypress} @keypressed = data[:name] puts("the key pressed is " + @keypressed.to_s) @next_test = true if(@key_test != nil) #if @key_test.include?(data[:name]) # @key_test.delete(data[:name]) if @key_test == data[:name] @key_test = nil end puts "KEY: #{data[:name]}" @view.displayDiret("KEY: #{data[:name]}", 2, :left) if(@key_test.size == 0) @key_test = nil end end elsif event =~ %r{comm/interrupted} # checking displayOn added to make sure "if display is on not to take picture because of pir" if($video_recording == false) if(((data[:pir] == true) && (@view.displayOn? == false)) || (data[:field_scan] == true)) pir_detected() else cameera_set_change(data) end end if ( (data[:power_button] == true) || (data[:accelerometer] == true) ) @turn_on_display_flag = true end if (data[:sms] == true) Log4Ienso.log.P_INFO("||||| SMS received when awake, ignoring it |||||") end elsif event =~ %r{comm/interrupt_accelerometer} @turn_on_display_flag = true elsif event =~ %r{sdcard/inserted} @sdcard_status = true elsif event =~ %r{sdcard/removed} @sdcard_status = false elsif event =~ %r{sdcard/diskSpace} @disk_space = data elsif event =~ %r{modem/started} puts("modem started") @modem_state = MODEM_CONNECTING elsif event =~ %r{modem/usbconnected} @modem_state = MODEM_PORTS_AVAILABLE Log4Ienso.log.P_NOTICE("modem ports avaialble") elsif event =~ %r{modem/connected} Log4Ienso.log.P_NOTICE("modem connected event received") @modem_state = MODEM_CONNECTED if @startmode != COLD_BOOT @comm.set_m0_rtc() end elsif event =~ %r{modem/startingupload} puts("modem starting photo upload") @modem_state = MODEM_STARTING_UPLOAD elsif event =~ %r{modem/finishedupload} puts("completed photo upload") @modem_state = MODEM_FINISHED_UPLOAD elsif event =~ %r{modem/fail} puts("modem or network lost") @modem_state = MODEM_OFF elsif event =~ %r{modem/sleeping} puts("modem sleeping") @modem_state = MODEM_IDLE elsif event =~ %r{modem/reboot} puts("modem needs reboot") #@modem_state = MODEM_REBOOT elsif event =~ %r{menu/field_scan} # puts('---------------------- menu/field_scan ------ event listener') @set_field_scan_flag=true elsif event =~ %r{menu/refresh} @isMenuDirty = true Log4Ienso.log.P_NOTICE(' menu/refresh -- event received') elsif event =~ %r{camera/deleteall} Log4Ienso.log.P_NOTICE(' delete all -- event received') deleteallMediaFiles elsif event =~ %r{camera/takepic} Log4Ienso.log.P_NOTICE("SMS triggered / profile changed photo request") if((@mutex_sleep != nil)&&( @mutex_sleep.try_lock == true) && (@hotspot == 0) && ( check_photo_mode == true)) @wq_cap.enqueue_p(method(:take_picture)) else Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} =====Warning: Event camera/takepic ignored because of mutex_sleep could not be locked") end @mutex_sleep.unlock elsif event =~ %r{menu/time_ofoperation} puts("---------------------- menu/time_ofoperation ------ event listener #{data}") packet=[0x0d, data[:days_id], data[:blk_id], data[:off_on], data[:hr], data[:min] ] puts("------------------ control file packet =#{packet}") ret=@comm.set_m0_time_zone(packet) elsif event =~ %r{menu/pir_mode} puts("---------------------- menu/pir_mode ------ event listener #{data}") set_pir_mode() elsif event =~ %r{comm/initial} puts("---------------------- comm/initial ------ event listener #{data}") initial_M0() end end # This method handles key press events from the keypad. # # params: # # - code: The keycode of the key that was pressed. See Keypad for details. def pir_detected(data = nil) if((@mutex_sleep != nil)&&( @mutex_sleep.try_lock == true) && (@hotspot == 0) ) start_picture_video(false , data) else Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} =====Warning: Event pir_detected comm/interrupt ignored because of mutex_sleep could not be locked") end @mutex_sleep.unlock end def send_thumb_to_server(thumb) if(@env.get_env('wirless_on/off') == 'on') Log4Ienso.log.P_NOTICE("Thumbnail picture send to server #{thumb}") exit_code = 1 exit_code = @connmanager.uploadThumb(thumb) if(exit_code == 0) @upload_photo_count +=1 updatePhotoUploadCount end @picman.submit_thumb(thumb, exit_code) end end def test_start(start_name, line2 = " ") @start_name = start_name puts "====================== #{start_name} Start ======================" @view.displayDiret(start_name, 1, :center) @view.displayDiret(line2, 2, :center) end def test_end(result) str = "FAIL" @next_test = false if(result == true) str = "OK" end puts "====================== #{@start_name} #{str} ======================" @view.displayDiret("#{@start_name} #{str}", 1, :center) @view.displayDiret("press button", 2, :center) loop do if(@next_test == true) break; end sleep 0.1 end end def return_a_key() @keypressed = nil @keytest = nil sleep(0.2) loop do if(@keypressed != nil) break end sleep 0.1 end end def test_image_sensor() ret1 = @camera.capture_image(1) puts "Camera capture_image result [#{ret1}]" if(ret1 != nil) ret = true else ret = false end ret end def set_test_result( row = 0, pos = 0 , char = 'X') @test_result[row][pos] = char @view.displayDiret(@test_result[row], row+1, :left) puts "test_result = #{@test_result}" end def elapsed_routine(test) if(!@start_elapsed) return end @elapsed_time += 1 str = "TIME = #{@elapsed_time}" @view.displayDiret(str, 2, :left) @timer_elapsed.start(false, 1); end def cursor_routine(test) if(!@start_cursor) return end str = @test_result[@cursor_row] [0..15] # if remove the last part it will be by reference @cursor_toggle = !@cursor_toggle if(@cursor_toggle) if(str[@cursor_pos] == 'X') if(@cursor_pos < 9) str[@cursor_pos] =(@cursor_pos+1).to_s else case @cursor_pos when 9 char = 'A' when 10 char = 'B' when 11 char = 'C' when 12 char = 'D' when 13 char = 'E' when 14 char = 'F' else char = 'F' end str[@cursor_pos] = char end else str[@cursor_pos] = '-' end end @view.displayDiret(str, @cursor_row+1, :left) @timer_cursor.start(false, 0.5); end def start_cursor_inc_pressedkey() @timer_cursor.start(false, 0.5); @start_cursor = true @pressed_times += 1 end def apply_result(key, nextkey, row=0, pos =0, res = 'X', res_pressed_times = false) @start_cursor = false @key_result = key case key when 'Enter' @key_result = nextkey @test_result[row][pos] = res if(res_pressed_times) @pressed_times = 0 end when 'Menu' @key_result = nextkey @test_result[row][pos] = 'X' if(res_pressed_times) @pressed_times = 0 end else if(key != nextkey) @pressed_times = 0 end end @view.displayDiret(@test_result[row], row+1, :left) end def test_One_Key(key = nil) @view.displayDiret("PRESS KEY #{key}", 1, :left) @view.displayDiret(" ", 2, :left) sleep (0.3) @key_test = key loop do if(@key_test == nil) @testcount+=1 puts " key #{key} detectiton was succesfull" break end sleep (0.3) end #test_end(true) end def init_cur_row_pos_keypressed_keytest(row=0, pos = 0, keypres = nil,keytest = nil) @cursor_row = row @cursor_pos = pos @keypressed = keypres @keytest = keytest end #------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- def test_routine() #startModem(@env.get_env_value('Select_Network'),0) #puts("modem started") @pressed_times = 0 ret=@comm.start_board_testing() #should be moved to early stage sleep(1) @timer_elapsed.start(false, 1); test_keypad() if( test_LCD() ) set_test_result( 0, 1, '2') else set_test_result( 0, 1, ) end sleep(0.1) if( test_image_sensor() ) set_test_result( 0, 2, '3') else set_test_result( 0, 2, ) end sleep(0.2) @keypressed = nil # 'Up' @pressed_times = 0 loop do while @keypressed == nil @pressed_times = 0 #start_cursor_inc_pressedkey() key = test_WIFI() apply_result(key, 'Auto', 0, 10, 'B') #start_cursor_inc_pressedkey() key = test_Modem() apply_result(key, 'Auto', 0, 11, 'C') #start_cursor_inc_pressedkey() key = test_sim() apply_result(key, 'Auto', 0, 12, 'D') #start_cursor_inc_pressedkey() key,res = test_GPS() apply_result(key, 'Auto', 0, 13, res) #start_cursor_inc_pressedkey() #check_bat_level() level = @comm.get_battery_level()#@view.get_battery() level = level / 10 puts"battery level is #{level} battery test passed" res1 = level.to_s key = 'Enter' apply_result(key, 'Auto', 0, 14, res1) sleep(1) end @key_result = @keypressed loop do case @key_result when 'Up' start_cursor_inc_pressedkey() case @pressed_times when 1 key = ir_cut_test() apply_result(key,'Up', 0, 3, '4') next when 2 puts "mic test" key = mic_test() apply_result(key, 'Down', 0, 4, '5', true) next else @pressed_times = 0 end when 'Down' start_cursor_inc_pressedkey() case @pressed_times when 1 key = ir_led_test() apply_result(key, 'Down', 0, 5, '6') next when 2 key = led_test() apply_result(key, 'Left', 0, 6, '7', true) next else @pressed_times = 0 end when 'Left' start_cursor_inc_pressedkey() case @pressed_times when 1 key = pir_test() apply_result(key, 'Left', 0, 7, '8') next when 2 key = accel_test() apply_result(key, 'Left', 0, 8, '9') next when 3 key = photocell_test() apply_result(key, 'Auto', 0, 9, 'A',true) break else @pressed_times = 0 end when 'Auto' @keypressed = nil @pressed_times = 0 sleep(1) break else @keypressed = nil sleep(0.3) break end end next end ret=@comm.stop_board_testing() end #------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- def test_keypad() puts "------------------------------ test_keypad() ----------------------------------" test_One_Key("Menu") @start_elapsed = false sleep(0.2) test_One_Key("Up") sleep(0.2) test_One_Key("Right") sleep(0.2) test_One_Key("Down") sleep(0.2) test_One_Key("Left") sleep(0.2) test_One_Key("Enter") sleep(0.2) #result = @testcount.to_s + "of 12 pass" #puts(result) set_test_result( 0, 0, '1') end def test_LCD() puts "---------------------------- test_LCD() ----------------------------------" @view.display_turn_on_all_pixels sleep (0.2) @keypressed = nil @keytest = nil sleep(0.2) loop do if(@keypressed != nil) if( (@keypressed == 'Enter') || (@keypressed == 'Menu') ) puts "key pressed = #{@keypressed}" break else @keypressed = nil end end sleep 0.2 end if(@keypressed == 'Enter') ret = true puts "lcd passed" else ret = false puts "lcd failed" end @testcount+=1 @view.displayDiret("XXXXXXXXXXXXXXX ", 1, :left) @view.displayDiret(" ", 2, :left) ret end def ir_cut_test() puts "------------------------------ ir_cut_test() ----------------------------------" init_cur_row_pos_keypressed_keytest(0 , 3) ir_cut_toggle = false while @keypressed == nil ir_cut_toggle = ! ir_cut_toggle if(ir_cut_toggle) @camera.set_night2() else @camera.set_day2() end sleep(1) end @keypressed end def mic_test() puts "------------------------------ mic_test() N/A has to be done later ----------------------------------" init_cur_row_pos_keypressed_keytest(0 , 4) #while @keypressed == nil # sleep(0.5) #end @keypressed = "Menu" end def ir_led_test() puts "------------------------------ ir_led_test() ----------------------------------" sleep(0.5) init_cur_row_pos_keypressed_keytest( 0, 5) `echo 1 > /sys/devices/platform/sunxi_vfe.0/vfe_attr/vfe_enable_ir_led` sleep(0.2) `i2cset -y 1 0x30 0x01 0xaa` sleep(0.2) `i2cset -y 1 0x30 0x08 0x06` #10` sleep(0.2) `i2cset -y 1 0x30 0x0b 0x06` #10` sleep(0.2) `i2cset -y 1 0x30 0x02 0x4f` sleep(0.2) `i2cset -y 1 0x30 0x0f 0x03` sleep(0.2) while @keypressed == nil sleep(0.2) end `echo 0 > /sys/devices/platform/sunxi_vfe.0/vfe_attr/vfe_enable_ir_led` sleep(0.2) @keypressed end def led_test() puts "------------------------------ led_test() ----------------------------------" init_cur_row_pos_keypressed_keytest(0 , 6) while @keypressed == nil `i2cset -y 1 0x36 0x10 0x10` sleep(0.2) `i2cset -y 1 0x36 0x10 0x08` sleep(0.2) `i2cset -y 1 0x36 0x10 0x04` sleep(0.2) `i2cset -y 1 0x36 0x10 0x02` sleep(0.2) `i2cset -y 1 0x36 0x10 0x01` sleep(0.2) end `i2cset -y 1 0x36 0x10 0x00` @keypressed end def pir_test() puts "------------------------------ pir_test() ----------------------------------" init_cur_row_pos_keypressed_keytest(0 , 7) while @keypressed == nil ret=@comm.pir_board_testing() if(ret == (23*256+1)) @keypressed = 'Enter' return @keypressed else sleep(0.5) end end if( @keypressed == 'Up') || ( @keypressed == 'Left') || ( @keypressed == 'Down') else @keypressed = 'Left' end @keypressed end def accel_test() puts "------------------------------ accel_test() ----------------------------------" init_cur_row_pos_keypressed_keytest(0 , 8) while @keypressed == nil ret=@comm.accelerometer_board_testing() if(ret == (23*256+1)) @keypressed = 'Enter' return @keypressed else sleep(0.5) end end if( @keypressed == 'Up') || ( @keypressed == 'Left') || ( @keypressed == 'Down') else @keypressed = 'Left' end @keypressed end def photocell_test() puts "------------------------------ photocell_test() ----------------------------------" init_cur_row_pos_keypressed_keytest(0 , 9) while @keypressed == nil ret=@comm.adc_board_testing() if(ret == (23*256+1)) @keypressed = 'Enter' return @keypressed else sleep(0.5) end end if( @keypressed == 'Up') || ( @keypressed == 'Left') || ( @keypressed == 'Down') else @keypressed = 'Left' end @keypressed end def test_WIFI() puts "------------------------------ wifi_test() ----------------------------------" #test_start("WIFI") ifconfig = `ifconfig -a` #puts "test wifi ifconfig =#{ifconfig}" c = `ifconfig -a | grep wlan | wc -l` if c.chomp.strip.to_i > 0 puts("wifi pass") @keypressed = 'Enter' else puts("wifi failed") @keypressed = 'Menu' end @keypressed end def test_Modem() puts "------------------------------ modem_test() ----------------------------------" sleep(0.1) if @imei != nil puts("modem card found , @imei=#{@imei}") @imei1 = "imei: " + @imei[0..-13] @imei2 = @imei[-12..-1] if @imei.length > 10 puts("@imei.len>10 sim card found") @keypressed = 'Enter' else puts("@imei.len>10 sim not found") @keypressed = 'Menu' end else puts("@imei = nil sim not found") @keypressed = 'Menu' end @keypressed end def test_sim puts "----------------------------- sim_test() ----------------------------------" sleep(0.1) if @iccid != nil puts("sim card found , @iccid=#{@iccid}") @iccid1 = "ICCID: " + @iccid[0..-14] @iccid2 = @iccid[-13..-1] if @iccid.length > 10 puts("@iccid.len>10 sim card found") @keypressed = 'Enter' else puts("@iccid.len>10 sim not found") @keypressed = 'Menu' end else puts("@iccid = nil sim not found") @keypressed = 'Menu' end @keypressed end def test_GPS puts "------------------------------ gps_test() ----------------satellite no=#{@satNo}------------------" key = 'Menu' res = 'X' satno = @satNo if (satno > 0) key = 'Enter' if (satno > 9) satno = 9 end res = satno.to_s end return key, res end def test_LTE() puts "------------------------------ LTE_test() ----------------------------------" test_start("MODEM") #val = `lsusb | tr -s ' ' | cut -d' ' -f6 | head -1` #puts(val) @keypressed = nil count=0 if @modemFound == 1 puts("modem found") if @imei != nil if @imei.include? "at+cgsn" puts "String includes 'at+cgsn'" @imei = @imei[7..-1] puts(@imei) end @imei1 = "IMEI: " + @imei[0..-13] @imei2 = @imei[-12..-1] @view.displayDiret(@imei1, 1, :left) @view.displayDiret(@imei2, 2, :left) loop do if @keypressed != nil if @keypressed.strip.chomp == "Enter" count+=1 if count > 2 break end end end end end #if @iccid != nil # @view.displayDiret("ICCID: ", 1, :center) # @view.displayDiret(@iccid[-12..-1], 2, :center) # sleep(2) #end else puts("modem not found") @view.displayDiret("LTE check", 1, :center) @view.displayDiret("FAIL", 2, :center) @errcode = @errcode + "A" sleep(2) test_end(false) return end @testcount+=1 @view.displayDiret("Modem Result", 1, :center) @view.displayDiret("Passed", 2, :center) sleep(2) test_end(true) end def test_Camera() test_start("IMG SENSOR") #@camera = CameraControl.new(@config.camctrl, @env) ret = @camera.capture_image(1) puts "Camera capture_image result [#{ret}]" if(ret != nil) @testcount+=1 test_end(true) else @errcode = @errcode + "3" test_end(false) end end def take_picture_task( isresume = false, num = @env.get_env_value('capture_count')) @wq_cap.enqueue_p(method(:take_picture), isresume, 1) @remaining_pictures_no = num -1 if(@remaining_pictures_no > 0) @take_picture_in_process = true @timer_picture_burst.start(false,PICTURE_BURST_TIME) Log4Ienso.log.P_INFO("Taking several picture Started and @take_picture_in_process=#{@take_picture_in_process} and remaining number is #{@remaining_pictures_no}") else @take_picture_in_process = false end end def take_picture(isresume = false, num = @env.get_env_value('capture_count'), filter = nil) Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} -------------------------take pic start!!! resume=#{isresume}. #{Thread.current.object_id}") begin if(isresume) id = @camera.get_resume_take_pic(num) else id = @camera.capture_image(num, filter) end if(@env.get_env_value('imaage_interval') <= SLEEP_GUARD_TIME) @timer_sleep_guard.start(false,SLEEP_GUARD_TIME) end if(@sdcard_status == true) if(@env.get_env('overwrite') == 'on') numpic_bak = 0 while (@disk_space[:free] <= (@config.picman.min_free_disk)) && @sdcard_status && (@config.picman.min_free_disk < @disk_space[:total]) numpic = @picman.delete_oldest_pic() if(numpic_bak == numpic) break; end @numpic_bak = numpic Log4Ienso.log.P_INFO("DELETE OLDEST PIC #{numpic}") end end #save_picture(savepath, id) json = makejson() @picman.save_picture(id, json, @env.get_env('wirless_on/off') == 'on', @camera.get_day_night_state()) if @disk_space[:free] > @config.picman.min_free_disk end rescue Exception => e Log4Ienso.log.P_ERR("Exception: #{e}") Log4Ienso.log.P_ERR(e.backtrace) @log.error("Exception: #{e}") @log.error(e.backtrace) end Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} -------------------------take pic end !!!#{Thread.current.object_id}") end #update signal strength leds def setSignalStrengthLeds() r=0 r = @rssi r = r.to_i `i2cset -y 1 0x36 0x10 0x00` if r==0 `i2cset -y 1 0x36 0x10 0x10` if r==1 `i2cset -y 1 0x36 0x10 0x18` if r==2 `i2cset -y 1 0x36 0x10 0x1C` if r==3 `i2cset -y 1 0x36 0x10 0x1E` if r==4 `i2cset -y 1 0x36 0x10 0x1F` if r==5 end def take_video(num) length=@env.get_env_value('movie_length') Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} =============================== take_video starts, length=#{length} , id=#{Thread.current.object_id} ") begin id=@camera.capture_video(length) Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} =============================== take_video after capture_video ") #if(@env.get_env_value('movie_interval') <= SLEEP_GUARD_TIME) # @timer_sleep_guard.start(false,SLEEP_GUARD_TIME) #end if(@sdcard_status == true) if(@env.get_env('overwrite') == 'on') numvid_bak = 0 while (@disk_space[:free] <= (@config.picman.min_free_disk)) && @sdcard_status && (@config.picman.min_free_disk < @disk_space[:total]) numvid = @picman.delete_oldest_vid() if(numvid_bak == numvid) break; end @numvid_bak = numvid Log4Ienso.log.P_INFO("DELETE OLDEST VID #{numvid}") end end #save_picture(savepath, id) json = nil #makejson() @picman.save_video(id, @env.get_env('movie_resoluition'), @env.get_env('wirless_on/off') == 'on', @camera.get_day_night_state()) if @disk_space[:free] > @config.picman.min_free_disk end rescue Exception => e Log4Ienso.log.P_ERR("Exception: #{e}") Log4Ienso.log.P_ERR(e.backtrace) @log.error("Exception: #{e}") @log.error(e.backtrace) end Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} =============================== take_video ends !!! id=#{Thread.current.object_id}") $video_recording = false @timer_lcd_off.start(false, @env.get_env_value('lcd_off_time')) end def check_bat_level() @read_bat_counter += 1 if(@read_bat_counter > 100) @read_bat_counter = 0 if ((@view != nil) && (@comm != nil)) level = @comm.get_battery_level() @battery = level @view.set_battery (level) Log4Ienso.log.P_INFO("battery level is [#{level} percent") end end end def sleep_control( param = nil) # Timeout Goto Suspend Mode #if(@timer_lcd_off.stop?) # @view.displayOff() #else # @view.view_update() #end @mutex_sleep.lock if(@testcount == 0) puts ("[#{@sleep_con_check}] going to sleep #{@wq_cap.cur_tasks} #{@modem_state} #{@timer_sleep_guard.stop?} #{@timer_lcd_off.stop?}") @view.displayOn() #@view.displayDiret("Wait for modem", 1, :center) #@view.displayDiret("wait 20 sec", 2, :center) @connmanager.enableGPS() puts("running test function") @view.displayDiret("Starting ..", 1, :left ) #@view.displayDiret("Press button", 2, :center) sleep(0.1) #startModem(@env.get_env_value('Select_Network'),0) #puts("modem started") test_routine() @view.displayDiret("Test Finished", 1, :left) result = @testcount.to_s + "of 12 pass" puts(result) @view.displayDiret(result, 2, :center) sleep(0.5) @view.displayDiret(result, 2, :center) sleep(2) @view.displayDiret("Test sleep", 1, :center) @view.displayDiret("wake on PIR", 2, :center) sleep(2) @view.displayOff() @sleep_con_check = 0; @comm.interrupt_mask(true) @wq_cap.join @thread_modem.kill if @thread_modem != nil @thread_photo.join if @thread_photo != nil @thread_photo = nil; @picman.enter_sleep(true) @camera.req_resume_take_pic(@env.get_env_value('capture_count')) puts("enter suspend") @log.info("enter suspend") system(%Q(echo mem > /sys/power/state)) puts("-------------------------------------------------------") puts("wake up") @log.info("wake up") @modem_state = MODEM_OFF #if(@env.get_env('wirless_on/off') == 'on') # @thread_modem = Thread.new { startModemandNetwork(@env.get_env_value('Select_Network')) } # @thread_photo = Thread.new { sendPhotos } #end reason = @comm.check_wakeup_reason @comm.interrupt_mask(false) @view.displayOn() #@thread_modem = Thread.new { startModem(@env.get_env_value('Select_Network'),COLD_BOOT) } @testcount += 1 #@view.displayDiret("Tests Finished", 1, :center) result = @testcount.to_s + "of 13 pass" puts(result) @view.displayDiret(result, 1, :center) finalcode="Code: " + @errcode @view.displayDiret(finalcode, 2, :center) #run_test_function() #end else @sleep_con_check += 1 if (@sleep_con_check > 20) puts ("[#{@sleep_con_check}] cat't go to sleep #{@wq_cap.cur_tasks} #{@modem_state} #{@timer_sleep_guard.stop?} #{@timer_lcd_off.stop?}") @sleep_con_check = 0 end if @modemstarttime != nil elapsedTime = Time.now - @modemstarttime puts("elapsed time is" + elapsedTime.to_s) if( (elapsedTime > 60 && elapsedTime < 300) && ( @modem_state == MODEM_CONNECTING || @modem_state == MODEM_CONNECTED || @modem_state == MODEM_STARTING_UPLOAD )) puts("FORCING modem shutdown...") @modem_state = MODEM_IDLE end end end if(@mutex_sleep.locked?) @mutex_sleep.unlock end end end #returns true if photo mode def check_photo_mode ret = false cap_mode = @env.get_env_value('capture_mode') if(cap_mode == 'image') ret = true end ret end def get_interval_no(str) ret=@env.get_selected_idx(str) if(ret == 0) ret = 1 elsif(ret < 4) ret=ret * 5 elsif(ret == 4) ret = 30 else ret = 60 end ret end def get_hr_min(str1) str=@env.get_env_value(str1) hr1 = get_int_val(str[0].to_i,str[1].to_i) min1= get_int_val(str[3].to_i,str[4].to_i) hr_bcd = int_to_bcd_bytes(hr1) min_bcd = int_to_bcd_bytes(min1) ret=[hr_bcd, min_bcd] end def get_int_val(no1, no2) ret=no1 *10 + no2 end def set_field_scan() ret=@comm.set_m0_rtc() i1=@env.get_selected_idx('field_scan') i2=get_interval_no('interval_a') hr_min_1= get_hr_min('start_time_a') hr_min_2= get_hr_min('end_time_a') packet=[0x09, 0x00, i1 & 0xff, hr_min_1[0] & 0xff, hr_min_1[1] & 0xff, i2 & 0xff, hr_min_2[0] & 0xff, hr_min_2[1] & 0xff] # puts("------------------ control file packet =#{packet}") ret=@comm.set_m0_field_scan(packet) i2=get_interval_no('interval_b') hr_min_1= get_hr_min('start_time_b') hr_min_2= get_hr_min('end_time_b') packet=[0x09, 0x01, i1 & 0xff, hr_min_1[0] & 0xff, hr_min_1[1] & 0xff, i2 & 0xff, hr_min_2[0] & 0xff, hr_min_2[1] & 0xff ] # puts("------------------ control file packet =#{packet}") ret=@comm.set_m0_field_scan(packet) @set_field_scan_flag=false end def get_hr_min_too(days_idx) str=@env.get_env('time_ofoperation.time') str1=str[days_idx] if str != nil str1=str1.split('/') ret = [] str1.each do | time | hr = get_int_val(time[0].to_i,time[1].to_i) min = get_int_val(time[3].to_i,time[4].to_i) ret.push(hr, min) end puts("=========== get_hr_min_too return=#{ret}") ret end def get_offon_too(days_idx) str=@env.get_env('time_ofoperation.off_on') str1=str[days_idx] if str != nil str1=str1.split('/') ret = 0 power=1 str1.each do | offon | if (offon == '1' ) ret += power end power *=2 end puts("=========== get_offon_too return=#{ret}") ret end def deleteallMediaFiles system("rm -rf /media/photos/DCIM/*") #TODO we should change it later system("rm -rf /media/photos/thumb/*") #TODO we should change it later system("sync") @picman.get_num_photos() if @picman != nil @picman.get_num_videos() if @picman != nil end def int_to_bcd_bytes(int) h10 = ((int / 10) & 0x0f) << 4 h1 = (int % 10) & 0x0f hr = h10 | h1 hr end def turn_on_display() if($video_recording == true) @timer_lcd_off.start(false, 'never') else @timer_lcd_off.start(false, @env.get_env_value('lcd_off_time')) end if (@view.displayOn? == false) @read_bat_counter = 100 check_bat_level() setSignalStrengthLeds() #switch on LED @view.displayOn() end end def chk_power_key(keyno) if @view != nil if ((keyno & 0x8) == 0x8 || (keyno & 0x10) == 0x10) turn_on_display() if ((keyno & 0x8) == 0x8) puts(" --------------- long power key=#{keyno}") @view.displayDiret("POWER DOWN ?", 1, :left) @view.displayDiret("HIT OK TO CONT.", 2, :left) @view.pwr_shut_down(true) else # puts(" --------------- short power key") @view.pwr_shut_down(false) end @view.view_update() end end end options = { } optparse = OptionParser.new{|opt| opt.banner = 'This is the service template' opt.on('-cPATH', '--config=PATH', 'Location of the config file.'){|arg| raise("File #{arg} does not exit.") if not File.exists?(arg) options[:config_path] = arg } } optparse.parse! begin options.assert_keys(:config_path) rescue puts("--config=path must be specified") exit(-1) end begin con = Control.new(YAML.load(File.read(options[:config_path])).to_hashugar) puts "Initial Done" loop{ con.sleep_control() sleep(0.1); } rescue Exception => e puts("Exception: #{e}") puts(e.backtrace) log = Syslog::Logger.new("wtc2.0") log.fatal("Exception: #{e}") log.fatal(e.backtrace) end opt/wtc2.0/src/primos_config_v0.0.1.yaml0000644000175200017520000003545013557057144020350 0ustar bushnellbushnell global: logger: Logger(STDOUT) storage_location: /media/photos/ remote: url: https:// mqtt: control: topic: control uri: mqtt://localhost ledctrl: topic: ledctrl uri: mqtt://localhost camctrl: topic: camctrl uri: mqtt://localhost keypadctrl: topic: keypadctrl uri: mqtt://localhost lcdctrl: topic: lcdctrl uri: mqtt://localhost camera: default_resolution: height: 3264 width: 2160 control: log_name: wtc2-control ledctrl: log: wtc2-ledctrl gpios: - PD29 ltectrl: log_name: wtc2-ltemodem gpio: power: number: PE19 direction: out value: 0 modem: number: PE12 direction: out value: 0 vbus: number: PD20 direction: out value: 0 tty_data: /dev/ttyUSB2 tty_command: /dev/ttyUSB3 tty_ghostport: /dev/ttyUSB5 tty_list: /dev/ttyU* tty_port_count: 4 network: rogers_can: apn: ltemobile.apn username: password: pdp: 1 iptype: IP dialcode: ATD*99# verizon: apn: vzwinternet username: password: pdp: 3 iptype: IPV4V6 dialcode: ATD*99***3# atandt: apn: bnwtc.zipitwireless.com.attz username: password: pdp: 1 iptype: IP dialcode: ATD*99# rogers_us: apn: m2minternet.apn username: password: pdp: 1 iptype: IP dialcode: ATD*99# kpn: apn: internet.m2m username: password: pdp: 1 iptype: IP dialcode: ATD*99# bellca: apn: mnet.bell.ca.ioe username: password: pdp: iptype: dialcode: timeserver: time.nist.gov cloud_service_provider: zipit: end_point: https://wtcbush:tipiz@dev2.wirelesstrophycam.com:8001 lte_config: config_folder: /var/wtc2.0 config_file: lte.config token_file: session.id lcdctrl: log_name: wtc2-lcdctrl gpios_ctrl: EN: PD12 RW: PD13 RS: PD14 PWM: PD28 POWER: pD29 BLK: PC7 KBD_POWER: PD25 gpios_bus: d0: PD2 d1: PD3 d2: PD4 d3: PD5 d4: PD6 d5: PD7 d6: PD10 d7: PD11 m0ctrl: log_name: m0ctrl tty: /dev/ttyS4 gpio_int: :gpio: PH9 :name: M0 interrupt :edge: 'rising' gpio_reset: PE8 actions: no_sd_card: proc{puts("hello")} keypadctrl: log_name: wtc-keypadctrl buttons: - :gpio: PL3 :name: Up :edge: 'falling' - :gpio: PL7 :name: Down :edge: 'falling' - :gpio: PL5 :name: Left :edge: 'falling' - :gpio: PL6 :name: Right :edge: 'falling' - :gpio: PL4 :name: Enter :edge: 'falling' - :gpio: PL2 :name: Escape :edge: 'falling' camctrl: log_name: wtc2-camctrl default_resolution: height: 1080 width: 1920 ir_leds: gpios: enable_positive: PD15 high_current_enable: PD18 ir_filter: gpios: power: PD21 direction_positive: PD22 present_signal_value: 0 # GPIO signal (high/low) value to indicate the IR cut filter is in front of the lens missing_signal_value: 1 # GPIO signal (high/low) value to indicate the IR cut filter is _not_ in front of the lens default_setting: present # daytime operation pulse_width: 0.100 # 100ms voltage pulse to move the filter. cap_application: path: /opt/wtc2.0/capture/ txfifo: /tmp/bushnell-trailcam-fifo-to-c rxfifo: /tmp/bushnell-trailcam-fifo-to-ruby pid_file: /var/run/wtc2-capture.pid gps: tty: /dev/ttyS1 gpios: green_led: red_led: blue_led: button_up: picman: log_name: wtc2-picman pic_path: /media/photos/DCIM/ thumb_path: /media/photos/thumb/ input_path: /tmp/ max_error_count: 50 min_free_disk: 10240 messages: no_sd_card: SD card is missing. Picture not saved. mqtt_connection: default: Failed to connect to MQTT broker def_env: reset_cntr: selected: '0' reset_time: selected: '0' path: 'env/' name: 'env.yml' desc_file: selected: 'desc_en.yml' candidate: - 'desc_en.yml' - 'desc_kr.yml' - 'desc_fr.yml' lcd_off_time: selected: '20_second' candidate: - '10_second' - '20_second' - '40_second' - 'never' time_ofoperation: enable: selected: 'off' candidate: - 'off' - 'on' days: selected: 'mon_fri' candidate: - 'mon_fri' - 'sat' - 'sun' off_on: selected: - '0/0/0/0' - '0/0/0/0' - '0/0/0/0' time: selected: - '00:00/06:00/12:00/18:00' - '00:00/06:00/12:00/18:00' - '00:00/06:00/12:00/18:00' Set_photocell: selected: '100' candidate: - '100' - '150' - '200' - '250' - '300' - '350' - '400' - '450' - '500' Select_Network: selected: 'ROGERS-US' candidate: - 'ATT' - 'KPN' - 'VERIZON' - 'ROGERS-US' - 'ROGERS-CAN' lcd_force_on: selected: 'off' candidate: - 'on' - 'off' camera_name: selected: CAMERA1 wirless_on/off: selected: 'on' candidate: - 'on' - 'off' report_interval: selected: 'now' candidate: - 'now' - 'daily' - 'never' overwrite: selected: 'on' candidate: - 'on' - 'off' capture_mode: selected: 'image' candidate: - 'image' - 'video' #- 'hybrid' hybrid: selected: 'off' candidate: - 'off' - 'on' capture_count: selected: '1_copy' candidate: - '1_copy' - '2_copy' - '3_copy' - '4_copy' - '5_copy' shutter_speed: selected: 'med' candidate: - 'low' - 'med' - 'high' image_resoluition: selected: '8' candidate: - '2' - '5' - '8' - '20' movie_resoluition: selected: '720p30' candidate: - '720p30' - '1080p30' - '640x480' #- '960x540' movie_length: selected: '10_second' candidate: #- '1_second' #- '2_second' #- '3_second' #- '4_second' - '5_second' - '6_second' - '7_second' - '8_second' - '9_second' - '10_second' - '15_second' - '20_second' - '25_second' - '30_second' - '35_second' - '40_second' - '45_second' - '50_second' - '55_second' - '60_second' movie_interval: selected: '10_second' candidate: - '1_second' - '2_second' - '3_second' - '4_second' - '5_second' - '6_second' - '7_second' - '8_second' - '9_second' - '10_second' - '15_second' - '20_second' - '25_second' - '30_second' - '35_second' - '40_second' - '45_second' - '50_second' - '55_second' - '60_second' imaage_interval: selected: '10_second' candidate: - '1_second' - '2_second' - '3_second' - '4_second' - '5_second' - '6_second' - '7_second' - '8_second' - '9_second' - '10_second' - '15_second' - '20_second' - '25_second' - '30_second' - '35_second' - '40_second' - '45_second' - '50_second' - '55_second' #- '60_second' - '1_minute' - '2_minute' - '3_minute' - '4_minute' - '5_minute' - '6_minute' - '7_minute' - '8_minute' - '9_minute' - '10_minute' - '15_minute' - '20_minute' - '25_minute' - '30_minute' - '35_minute' - '40_minute' - '45_minute' - '50_minute' - '55_minute' - '60_minute' led_power: selected: 'med' candidate: - 'low' - 'med' - 'high' pic_format: selected: '3to2' candidate: - '3to2' - '16to9' show_timestamp: selected: 'on' candidate: - 'on' - 'off' field_scan: selected: 'off' candidate: - 'off' - 'on' scan_ab: selected: 'a_char' candidate: - 'a_char' - 'b_char' interval_a: selected: '5_minute2' candidate: - '1_minute2' - '5_minute2' - '10_minute2' - '15_minute2' - '30_minute2' - '60_minute2' interval_b: selected: '5_minute2' candidate: - '1_minute2' - '5_minute2' - '10_minute2' - '15_minute2' - '30_minute2' - '60_minute2' start_time_a: selected: '05:00' end_time_a: selected: '09:00' start_time_b: selected: '15:00' end_time_b: selected: '20:00' embedded_gps: selected: 'on' candidate: - 'on' - 'off' latitude: selected: "N 43°51'15.2\"" longitude: selected: "W 079°23'01.5\"" diagnostics: selected: 'off' candidate: - 'on' - 'off' gps_tracking: selected: 'off' candidate: - 'on' - 'off' switch_on/off_gps: selected: 'off' candidate: - 'on' - 'off' pir_mode: selected: 'on' candidate: - 'on' - 'day' - 'night' - 'timer' - 'off' pir: selected: 'auto' candidate: - 'auto' - 'high' - 'med' - 'low' file_logging: selected: 'off' candidate: - 'on' - 'off' tracking: selected: 'off' candidate: - 'on' - 'off' dailycheckin: selected: 0 candidate: - 0 - 1 - 2 activecommstate: #to manage server connection across reboots selected: 0 candidate: - 0 # now - 1 # daily mode - 2 # never provider: '310': country: "us" mnc_digits: 3 providers: '038': name: 'AT&T' apn: 'bnwtc.zipitwireless.com.attz' '090': name: 'AT&T' apn: 'bnwtc.zipitwireless.com.attz' '150': name: 'AT&T' apn: 'bnwtc.zipitwireless.com.attz' '170': name: 'AT&T' apn: 'bnwtc.zipitwireless.com.attz' '410': name: 'AT&T' apn: 'bnwtc.zipitwireless.com.attz' '560': name: 'AT&T' apn: 'bnwtc.zipitwireless.com.attz' '680': name: 'AT&T' apn: 'bnwtc.zipitwireless.com.attz' '004': name: 'VERIZON' apn: 'vzwinternet' '012': name: "VERIZON" apn: "vzwinternet" '311': country: "us" mnc_digits: 3 providers: '038': name: 'AT&T' apn: 'bnwtc.zipitwireless.com.attz' '090': name: 'AT&T' apn: 'bnwtc.zipitwireless.com.attz' '150': name: 'AT&T' apn: 'bnwtc.zipitwireless.com.attz' '170': name: 'AT&T' apn: 'bnwtc.zipitwireless.com.attz' '410': name: 'AT&T' apn: 'bnwtc.zipitwireless.com.attz' '560': name: 'AT&T' apn: 'bnwtc.zipitwireless.com.attz' '680': name: 'AT&T' apn: 'bnwtc.zipitwireless.com.attz' '480': name: 'VERIZON' apn: 'vzwinternet' '012': name: "VERIZON" apn: "vzwinternet" '302': country: "canada" mnc_digits: 3 providers: '720': name: "ROGERS_CANADA" apn: "m2minternet.apn" '220': name: "telus" apn: "telus_apn" '204': country: "holand" mnc_digits: 2 providers: '08': name: "KPN" apn: "internet.m2m" '10': name: "KPN" apn: "internet.m2m" opt/wtc2.0/src/color.rb0000644000175200017520000000172213557057144015362 0ustar bushnellbushnell Encoding.default_external = Encoding::UTF_8 Encoding.default_internal = Encoding::UTF_8 ANSI_C_RESET = "\033[0m" ANSI_C_RED = "\033[1;31m" ANSI_C_GREEN = "\033[1;32m" ANSI_C_YELLOW = "\033[1;33m" ANSI_C_BLUE = "\033[1;34m" ANSI_C_MAGENTA = "\033[1;35m" ANSI_C_CYAN = "\033[1;36m" while (line = readline) begin line.gsub!(/^.*L4I:/,"") if line =~ /INFO:/ line = line.gsub(/^/,"#{ANSI_C_CYAN}").gsub(/$/,"#{ANSI_C_RESET}") end if line =~ /NOTICE:/ line = line.gsub(/^/,"#{ANSI_C_GREEN}").gsub(/$/,"#{ANSI_C_RESET}") end if line =~ /ERROR:/ line = line.gsub(/^/,"#{ANSI_C_RED}").gsub(/$/,"#{ANSI_C_RESET}") end if line =~ /WARNING/ line = line.gsub(/^/,"#{ANSI_C_YELLOW}").gsub(/$/,"#{ANSI_C_RESET}") end if line =~ /LTE/ line = line.gsub(/(LTE)/,"#{ANSI_C_BLUE}\1#{ANSI_C_RESET}") end rescue Exception => e puts e puts "[#{line}]" end print line end opt/wtc2.0/src/sysinfo.rb0000644000175200017520000032237413557057144015747 0ustar bushnellbushnell#!/usr/bin/ruby # The following is an instruction to rdoc. It specifies the main page for the documentation. # This directive must appear in a .rb file. We placed it here because this is the main # control of the application. # :main: README.txt $LOAD_PATH.push File.expand_path("..", __FILE__) $lastupdatetime = "1970-01-01T12:00:00" require 'yaml' require 'json' require 'optparse' require 'syslog/logger' require 'utils' require 'menu' require 'view' require 'timer' require 'comm' require 'env' require 'work_que' require 'camera' require 'keypad' require 'picture_manager' require "monitor" require "connection_manager" require 'version' require 'gpio' require 'mqtt' require 'debug' Thread.abort_on_exception = true class SysInfo @uMagicCode = "" @uHeaderVer = "" @uActiveSlot = "" @acUUID = "" @acManufacturerName = "" @acProductName = "" @acModelName = "" @acHardwareId = "" @acSerialNo = "" @acAliasName = "" @usSlot1Success = "" @usSlot1FailCnt = "" @acSlot1UbootVer = "" @acSlot1UbootDate = "" @acSlot1UbootTime = "" @acSlot1KernelVer = "" @acSlot1KernelDate = "" @acSlot1KernelTime = "" @acSlot1M0Ver = "" @acSlot1M0Date = "" @acSlot1M0Time = "" @acSlot1AppVer = "" @acSlot1AppDate = "" @acSlot1AppTime = "" @usSlot2Success = "" @usSlot2FailCnt = "" @acSlot2UbootVer = "" @acSlot2UbootDate = "" @acSlot2UbootTime = "" @acSlot2KernelVer = "" @acSlot2KernelDate = "" @acSlot2KernelTime = "" @acSlot2M0Ver = "" @acSlot2M0Date = "" @acSlot2M0Time = "" @acSlot2AppVer = "" @acSlot2AppDate = "" @acSlot2AppTime = "" @uSlot1FactVer = "" @uSlot1FactDate = "" @uSlot1FactTime = "" @uSlot1Boot0Ver = "" @uSlot1Boot0Date = "" @uSlot1Boot0Time = "" @uSlot1MbrVer = "" @uSlot1MbrDAte = "" @uSlot1MbrTime = "" @uSlot1ResVer = "" @uSlot1ResDate = "" @uSlot1ResTime = "" @uSlot1EnvVer = "" @uSlot1EnvDate = "" @uSlot1EnvTime = "" @uSlot1VfatVer = "" @uSlot1VfatDate = "" @uSlot1VfatTime = "" @uSlot1RootFsVer = "" @uSlot1RootFsDate = "" @uSlot1RootFsTime = "" @uSlot2FactVer = "" @uSlot2FactDate = "" @uSlot2FactTime = "" @uSlot2Boot0Ver = "" @uSlot2Boot0Date = "" @uSlot2Boot0Time = "" @uSlot2MbrVer = "" @uSlot2MbrDAte = "" @uSlot2MbrTime = "" @uSlot2ResVer = "" @uSlot2ResDate = "" @uSlot2ResTime = "" @uSlot2EnvVer = "" @uSlot2EnvDate = "" @uSlot2EnvTime = "" @uSlot2VfatVer = "" @uSlot2VfatDate = "" @uSlot2VfatTime = "" @uSlot2RootFsVer = "" @uSlot2RootFsDate = "" @uSlot2RootFsTime = "" MAGIC_CODE = 0 HEADER_VER = 1 ACTIV_SLOT = 2 UUID = 3 MANUFACTER_NAME = 4 PRODUCT_NAME = 5 MODEL_NAME = 6 HARDWARE_ID = 7 SERIOAL_NO = 8 ALIAS_NAME = 9 SLOT1_SUCCESS = 10 SLOT1_FAIL_CNT = 11 SLOT1_FACT_VER = 12 SLOT1_FACT_DATE = 13 SLOT1_FACT_TIME = 14 SLOT1_BOOT0_VER = 15 SLOT1_BOOT0_DATE = 16 SLOT1_BOOT0_TIME = 17 SLOT1_UBOOT_VER = 18 SLOT1_UBOOT_DATE = 19 SLOT1_UBOOT_TIME = 20 SLOT1_MBR_VER = 21 SLOT1_MBR_DATE = 22 SLOT1_MBR_TIME = 23 SLOT1_RES_VER = 24 SLOT1_RES_DATE = 25 SLOT1_RES_TIME = 26 SLOT1_ENV_VER = 27 SLOT1_ENV_DATE = 28 SLOT1_ENV_TIME = 29 SLOT1_KERNEL_VER = 30 SLOT1_KERNEL_DATE = 31 SLOT1_KERNEL_TIME = 32 SLOT1_VFAT_VER = 33 SLOT1_VFAT_DATE = 34 SLOT1_VFAT_TIME = 35 SLOT1_ROOTFS_VER = 36 SLOT1_ROOTFS_DATE = 37 SLOT1_ROOTFS_TIME = 38 SLOT1_APP_VER = 39 SLOT1_APP_DATE = 40 SLOT1_APP_TIME = 41 SLOT1_M0_VER = 42 SLOT1_M0_DATE = 43 SLOT1_M0_TIME = 44 SLOT2_SUCCESS = 45 SLOT2_FAIL_CNT = 46 SLOT2_FACT_VER = 47 SLOT2_FACT_DATE = 48 SLOT2_FACT_TIME = 49 SLOT2_BOOT0_VER = 50 SLOT2_BOOT0_DATE = 51 SLOT2_BOOT0_TIME = 52 SLOT2_UBOOT_VER = 53 SLOT2_UBOOT_DATE = 54 SLOT2_UBOOT_TIME = 55 SLOT2_MBR_VER = 56 SLOT2_MBR_DATE = 57 SLOT2_MBR_TIME = 58 SLOT2_RES_VER = 59 SLOT2_RES_DATE = 60 SLOT2_RES_TIME = 61 SLOT2_ENV_VER = 62 SLOT2_ENV_DATE = 63 SLOT2_ENV_TIME = 64 SLOT2_KERNEL_VER = 65 SLOT2_KERNEL_DATE = 66 SLOT2_KERNEL_TIME = 67 SLOT2_VFAT_VER = 68 SLOT2_VFAT_DATE = 69 SLOT2_VFAT_TIME = 70 SLOT2_ROOTFS_VER = 71 SLOT2_ROOTFS_DATE = 72 SLOT2_ROOTFS_TIME = 73 SLOT2_APP_VER = 74 SLOT2_APP_DATE = 75 SLOT2_APP_TIME = 76 SLOT2_M0_VER = 77 SLOT2_M0_DATE = 78 SLOT2_M0_TIME = 79 def setMagicCode( magicCode ) IO.binwrite("/dev/mmcblk0", magicCode.str, 0x800*512) end def getHeaderVer @uHeaderVer4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+4) @uHeaderVer3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+5) @uHeaderVer2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+6) @uHeaderVer1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+7) @uHeaderVer = (@uHeaderVer1.ord << 24) | (@uHeaderVer2.ord << 16) | (@uHeaderVer3.ord << 8) | @uHeaderVer4.ord return @uHeaderVer.to_i end def setHeaderVer( headerVer ) ver = (headerVer.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", ver.chr, 0x800*512+7) ver = (headerVer.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", ver.chr, 0x800*512+6) ver = (headerVer.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", ver.chr, 0x800*512+5) ver = headerVer.to_i & 0xFF IO.binwrite("/dev/mmcblk0", ver.chr, 0x800*512+4) end def setActiveSlot( activeSlot ) slot = (activeSlot.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot.chr, 0x800*512+11) slot = (activeSlot.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot.chr, 0x800*512+10) slot = (activeSlot.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot.chr, 0x800*512+9) slot = activeSlot.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot.chr, 0x800*512+8) end def setUUID( uUID ) IO.binwrite("/dev/mmcblk0", uUID.to_s, 0x800*512+12) end def setManufacturerName( manufacturerName ) IO.binwrite("/dev/mmcblk0", manufacturerName.to_s, 0x800*512+52) end def setProductName( productName ) IO.binwrite("/dev/mmcblk0", productName.to_s, 0x800*512+84) end def setModelName( modelName ) IO.binwrite("/dev/mmcblk0", modelName.to_s, 0x800*512+116) end def setHardwareId( hardwareId ) IO.binwrite("/dev/mmcblk0", hardwareId.to_s, 0x800*512+148) end def setSerialNo( serialNo ) IO.binwrite("/dev/mmcblk0", serialNo.to_s, 0x800*512+180) end def setAliasName( aliasName ) IO.binwrite("/dev/mmcblk0", aliasName.to_s, 0x800*512+244) end def setSlot1Success( slot1Success ) slot1S = (slot1Success.to_i >> 8 ) & 0xFF IO.write("/dev/mmcblk0", slot1S.chr, 0x800*512+277) slot1S = slot1Success.to_i & 0xFF IO.write("/dev/mmcblk0", slot1S.chr, 0x800*512+276) end def setSlot1FailCnt( slot1FailCnt ) slot1F = (slot1FailCnt.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1F.chr, 0x800*512+279) slot1F = slot1FailCnt.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot1F.chr, 0x800*512+278) end def setSlot1FactVer( slot1FactVer ) slot1FVer = (slot1FactVer.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1FVer.chr, 0x800*512+283) slot1FVer = (slot1FactVer.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1FVer.chr, 0x800*512+282) slot1FVer = (slot1FactVer.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1FVer.chr, 0x800*512+281) slot1FVer = slot1FactVer.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot1FVer.chr, 0x800*512+280) end def setSlot1FactDate( slot1FactDate ) slot1FDate = (slot1FactDate.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1FDate.chr, 0x800*512+287) slot1FDate = (slot1FactDate.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1FDate.chr, 0x800*512+286) slot1FDate = (slot1FactDate.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1FDate.chr, 0x800*512+285) slot1FDate = slot1FactDate.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot1FDate.chr, 0x800*512+284) end def setSlot1FactTime( slot1FactTime ) slot1FTime = (slot1FactTime.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1FTime.chr, 0x800*512+291) slot1FTime = (slot1FactTime.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1FTime.chr, 0x800*512+290) slot1FTime = (slot1FactTime.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1FTime.chr, 0x800*512+289) slot1FTime = slot1FactTime.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot1FTime.chr, 0x800*512+288) end def setSlot1Boot0Ver( slot1Boot0Ver ) slot1B0Ver = (slot1Boot0Ver.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1B0Ver.chr, 0x800*512+295) slot1B0Ver = (slot1Boot0Ver.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1B0Ver.chr, 0x800*512+294) slot1B0Ver = (slot1Boot0Ver.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1B0Ver.chr, 0x800*512+293) slot1B0Ver = slot1Boot0Ver.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot1B0Ver.chr, 0x800*512+292) end def setSlot1Boot0Date( slot1Boot0Date ) slot1B0Date = (slot1Boot0Date.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1B0Date.chr, 0x800*512+299) slot1B0Date = (slot1Boot0Date.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1B0Date.chr, 0x800*512+298) slot1B0Date = (slot1Boot0Date.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1B0Date.chr, 0x800*512+297) slot1B0Date = slot1Boot0Date.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot1B0Date.chr, 0x800*512+296) end def setSlot1Boot0Time( slot1Boot0Time ) slot1B0Time = (slot1Boot0Time.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1B0Time.chr, 0x800*512+303) slot1B0Time = (slot1Boot0Time.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1B0Time.chr, 0x800*512+302) slot1B0Time = (slot1Boot0Time.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1B0Time.chr, 0x800*512+301) slot1B0Time = slot1Boot0Time.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot1B0Time.chr, 0x800*512+300) end def setSlot1UbootVer( slot1UbootVer ) if (getHeaderVer == 0x1000000) IO.binwrite("/dev/mmcblk0", slot1UbootVer.to_s, 0x800*512+280) else slot1UVer = (slot1UbootVer.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1UVer.chr, 0x800*512+307) slot1UVer = (slot1UbootVer.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1UVer.chr, 0x800*512+306) slot1UVer = (slot1UbootVer.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1UVer.chr, 0x800*512+305) slot1UVer = slot1UbootVer.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot1UVer.chr, 0x800*512+304) end end def setSlot1UbootDate( slot1UbootDate ) if (getHeaderVer == 0x1000000) IO.binwrite("/dev/mmcblk0", slot1UbootDate.to_s, 0x800*512+296) else slot1UDate = (slot1UbootDate.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1UDate.chr, 0x800*512+311) slot1UDate = (slot1UbootDate.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1UDate.chr, 0x800*512+310) slot1UDate = (slot1UbootDate.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1UDate.chr, 0x800*512+309) slot1UDate = slot1UbootDate.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot1UDate.chr, 0x800*512+308) end end def setSlot1UbootTime( slot1UbootTime ) if (getHeaderVer == 0x1000000) IO.binwrite("/dev/mmcblk0", slot1UbootTime.to_s, 0x800*512+312) else slot1UTime = (slot1UbootTime.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1UTime.chr, 0x800*512+315) slot1UTime = (slot1UbootTime.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1UTime.chr, 0x800*512+314) slot1UTime = (slot1UbootTime.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1UTime.chr, 0x800*512+313) slot1UTime = slot1UbootTime.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot1UTime.chr, 0x800*512+312) end end def setSlot1MbrVer( slot1MbrVer ) slot1MbVer = (slot1MbrVer.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1MbVer.chr, 0x800*512+319) slot1MbVer = (slot1MbrVer.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1MbVer.chr, 0x800*512+318) slot1MbVer = (slot1MbrVer.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1MbVer.chr, 0x800*512+317) slot1MbVer = slot1MbrVer.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot1MbVer.chr, 0x800*512+316) end def setSlot1MbrDate( slot1MbrDate ) slot1MbDate = (slot1MbrDate.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1MbDate.chr, 0x800*512+323) slot1MbDate = (slot1MbrDate.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1MbDate.chr, 0x800*512+322) slot1MbDate = (slot1MbrDate.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1MbDate.chr, 0x800*512+321) slot1MbDate = slot1MbrDate.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot1MbDate.chr, 0x800*512+320) end def setSlot1MbrTime( slot1MbrTime ) slot1MbTime = (slot1MbrTime.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1MbTime.chr, 0x800*512+327) slot1MbTime = (slot1MbrTime.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1MbTime.chr, 0x800*512+326) slot1MbTime = (slot1MbrTime.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1MbTime.chr, 0x800*512+325) slot1MbTime = slot1MbrTime.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot1MbTime.chr, 0x800*512+324) end def setSlot1ResVer( slot1ResVer ) slot1RVer = (slot1ResVer.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1RVer.chr, 0x800*512+331) slot1RVer = (slot1ResVer.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1RVer.chr, 0x800*512+330) slot1RVer = (slot1ResVer.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1RVer.chr, 0x800*512+329) slot1RVer = slot1ResVer.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot1RVer.chr, 0x800*512+328) end def setSlot1ResDate( slot1ResDate ) slot1RDate = (slot1ResDate.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1RDate.chr, 0x800*512+335) slot1RDate = (slot1ResDate.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1RDate.chr, 0x800*512+334) slot1RDate = (slot1ResDate.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1RDate.chr, 0x800*512+333) slot1RDate = slot1ResDate.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot1RDate.chr, 0x800*512+332) end def setSlot1ResTime( slot1ResTime ) slot1RTime = (slot1ResTime.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1RTime.chr, 0x800*512+339) slot1RTime = (slot1ResTime.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1RTime.chr, 0x800*512+338) slot1RTime = (slot1ResTime.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1RTime.chr, 0x800*512+337) slot1RTime = slot1ResTime.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot1RTime.chr, 0x800*512+336) end def setSlot1EnvVer( slot1EnvVer ) slot1EVer = (slot1EnvVer.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1EVer.chr, 0x800*512+343) slot1EVer = (slot1EnvVer.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1EVer.chr, 0x800*512+342) slot1EVer = (slot1EnvVer.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1EVer.chr, 0x800*512+341) slot1EVer = slot1EnvVer.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot1EVer.chr, 0x800*512+340) end def setSlot1EnvDate( slot1EnvDate ) slot1EDate = (slot1EnvDate.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1EDate.chr, 0x800*512+347) slot1EDate = (slot1EnvDate.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1EDate.chr, 0x800*512+346) slot1EDate = (slot1EnvDate.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1EDate.chr, 0x800*512+345) slot1EDate = slot1EnvDate.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot1EDate.chr, 0x800*512+344) end def setSlot1EnvTime( slot1EnvTime ) slot1ETime = (slot1EnvTime.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1ETime.chr, 0x800*512+351) slot1ETime = (slot1EnvTime.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1ETime.chr, 0x800*512+350) slot1ETime = (slot1EnvTime.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1ETime.chr, 0x800*512+349) slot1ETime = slot1EnvTime.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot1ETime.chr, 0x800*512+348) end def setSlot1KernelVer( slot1KernelVer ) if (getHeaderVer == 0x1000000) IO.binwrite("/dev/mmcblk0", slot1KernelVer.to_s, 0x800*512+328) else slot1KerVer = (slot1KernelVer.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1KerVer.chr, 0x800*512+355) slot1KerVer = (slot1KernelVer.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1KerVer.chr, 0x800*512+354) slot1KerVer = (slot1KernelVer.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1KerVer.chr, 0x800*512+353) slot1KerVer = slot1KernelVer.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot1KerVer.chr, 0x800*512+352) end end def setSlot1KernelDate( slot1KernelDate ) if (getHeaderVer == 0x1000000) IO.binwrite("/dev/mmcblk0", slot1KernelDate.to_s, 0x800*512+344) else slot1KerDate = (slot1KernelDate.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1KerDate.chr, 0x800*512+359) slot1KerDate = (slot1KernelDate.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1KerDate.chr, 0x800*512+358) slot1KerDate = (slot1KernelDate.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1KerDate.chr, 0x800*512+357) slot1KerDate = slot1KernelDate.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot1KerDate.chr, 0x800*512+356) end end def setSlot1KernelTime( slot1KernelTime ) if (getHeaderVer == 0x1000000) IO.binwrite("/dev/mmcblk0", slot1KernelTime.to_s, 0x800*512+360) else slot1KerTime = (slot1KernelTime.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1KerTime.chr, 0x800*512+363) slot1KerTime = (slot1KernelTime.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1KerTime.chr, 0x800*512+362) slot1KerTime = (slot1KernelTime.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1KerTime.chr, 0x800*512+361) slot1KerTime = slot1KernelTime.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot1KerTime.chr, 0x800*512+360) end end def setSlot1VfatVer( slot1VfatVer ) slot1VfVer = (slot1VfatVer.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1VfVer.chr, 0x800*512+367) slot1VfVer = (slot1VfatVer.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1VfVer.chr, 0x800*512+366) slot1VfVer = (slot1VfatVer.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1VfVer.chr, 0x800*512+365) slot1VfVer = slot1VfatVer.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot1VfVer.chr, 0x800*512+364) end def setSlot1VfatDate( slot1VfatDate ) slot1VfDate = (slot1VfatDate.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1VfDate.chr, 0x800*512+371) slot1VfDate = (slot1VfatDate.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1VfDate.chr, 0x800*512+370) slot1VfDate = (slot1VfatDate.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1VfDate.chr, 0x800*512+369) slot1VfDate = slot1VfatDate.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot1VfDate.chr, 0x800*512+368) end def setSlot1VfatTime( slot1VfatTime ) slot1VfTime = (slot1VfatTime.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1VfTime.chr, 0x800*512+375) slot1VfTime = (slot1VfatTime.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1VfTime.chr, 0x800*512+374) slot1VfTime = (slot1VfatTime.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1VfTime.chr, 0x800*512+373) slot1VfTime = slot1VfatTime.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot1VfTime.chr, 0x800*512+372) end def setSlot1RootfsVer( slot1RootfsVer ) slot1RootVer = (slot1RootfsVer.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1RootVer.chr, 0x800*512+379) slot1RootVer = (slot1RootfsVer.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1RootVer.chr, 0x800*512+378) slot1RootVer = (slot1RootfsVer.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1RootVer.chr, 0x800*512+377) slot1RootVer = slot1RootfsVer.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot1RootVer.chr, 0x800*512+376) end def setSlot1RootfsDate( slot1RootfsDate ) slot1RootDate = (slot1RootfsDate.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1RootDate.chr, 0x800*512+383) slot1RootDate = (slot1RootfsDate.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1RootDate.chr, 0x800*512+382) slot1RootDate = (slot1RootfsDate.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1RootDate.chr, 0x800*512+381) slot1RootDate = slot1RootfsDate.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot1RootDate.chr, 0x800*512+380) end def setSlot1RootfsTime( slot1RootfsTime ) slot1RootTime = (slot1RootfsTime.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1RootTime.chr, 0x800*512+387) slot1RootTime = (slot1RootfsTime.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1RootTime.chr, 0x800*512+386) slot1RootTime = (slot1RootfsTime.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1RootTime.chr, 0x800*512+385) slot1RootTime = slot1RootfsTime.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot1RootTime.chr, 0x800*512+384) end def setSlot1AppVer( slot1AppVer ) if (getHeaderVer == 0x1000000) IO.binwrite("/dev/mmcblk0", slot1AppVer.to_s, 0x800*512+424) else slot1AVer = (slot1AppVer.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1AVer.chr, 0x800*512+391) slot1AVer = (slot1AppVer.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1AVer.chr, 0x800*512+390) slot1AVer = (slot1AppVer.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1AVer.chr, 0x800*512+389) slot1AVer = slot1AppVer.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot1AVer.chr, 0x800*512+388) end end def setSlot1AppDate( slot1AppDate ) if (getHeaderVer == 0x1000000) IO.binwrite("/dev/mmcblk0", slot1AppDate.to_s, 0x800*512+440) else slot1ADate = (slot1AppDate.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1ADate.chr, 0x800*512+395) slot1ADate = (slot1AppDate.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1ADate.chr, 0x800*512+394) slot1ADate = (slot1AppDate.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1ADate.chr, 0x800*512+393) slot1ADate = slot1AppDate.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot1ADate.chr, 0x800*512+392) end end def setSlot1AppTime( slot1AppTime ) if (getHeaderVer == 0x1000000) IO.binwrite("/dev/mmcblk0", slot1AppTime.to_s, 0x800*512+456) else slot1ATime = (slot1AppTime.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1ATime.chr, 0x800*512+399) slot1ATime = (slot1AppTime.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1ATime.chr, 0x800*512+398) slot1ATime = (slot1AppTime.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1ATime.chr, 0x800*512+397) slot1ATime = slot1AppTime.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot1ATime.chr, 0x800*512+396) end end def setSlot1M0Ver( slot1M0Ver ) if (getHeaderVer == 0x1000000) IO.binwrite("/dev/mmcblk0", slot1M0Ver.to_s, 0x800*512+376) else slot1MVer = (slot1M0Ver.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1MVer.chr, 0x800*512+403) slot1MVer = (slot1M0Ver.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1MVer.chr, 0x800*512+402) slot1MVer = (slot1M0Ver.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1MVer.chr, 0x800*512+401) slot1MVer = slot1M0Ver.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot1MVer.chr, 0x800*512+400) end end def setSlot1M0Date( slot1M0Date ) if (getHeaderVer == 0x1000000) IO.binwrite("/dev/mmcblk0", slot1M0Date.to_s, 0x800*512+392) else slot1MDate = (slot1M0Date.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1MDate.chr, 0x800*512+407) slot1MDate = (slot1M0Date.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1MDate.chr, 0x800*512+406) slot1MDate = (slot1M0Date.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1MDate.chr, 0x800*512+405) slot1MDate = slot1M0Date.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot1MDate.chr, 0x800*512+404) end end def setSlot1M0Time( slot1M0Time ) if (getHeaderVer == 0x1000000) IO.binwrite("/dev/mmcblk0", slot1M0Time.to_s, 0x800*512+408) else slot1MTime = (slot1M0Time.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1MTime.chr, 0x800*512+411) slot1MTime = (slot1M0Time.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1MTime.chr, 0x800*512+410) slot1MTime = (slot1M0Time.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot1MTime.chr, 0x800*512+409) slot1MTime = slot1M0Time.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot1MTime.chr, 0x800*512+408) end end def setSlot2Success( slot2Success ) slot2S = (slot2Success.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2S.chr, 0x800*512+473) slot2S = slot2Success.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot2S.chr, 0x800*512+472) end def setSlot2FailCnt( slot2FailCnt ) slot2F = (slot2FailCnt.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2F.chr, 0x800*512+475) slot2F = slot2FailCnt.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot2F.chr, 0x800*512+474) end def setSlot2FactVer( slot2FactVer ) slot2FVer = (slot2FactVer.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2FVer.chr, 0x800*512+479) slot2FVer = (slot2FactVer.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2FVer.chr, 0x800*512+478) slot2FVer = (slot2FactVer.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2FVer.chr, 0x800*512+477) slot2FVer = slot2FactVer.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot2FVer.chr, 0x800*512+476) end def setSlot2FactDate( slot2FactDate ) slot2FDate = (slot2FactDate.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2FDate.chr, 0x800*512+483) slot2FDate = (slot2FactDate.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2FDate.chr, 0x800*512+482) slot2FDate = (slot2FactDate.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2FDate.chr, 0x800*512+481) slot2FDate = slot2FactDate.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot2FDate.chr, 0x800*512+480) end def setSlot2FactTime( slot2FactTime ) slot2FTime = (slot2FactTime.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2FTime.chr, 0x800*512+487) slot2FTime = (slot2FactTime.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2FTime.chr, 0x800*512+486) slot2FTime = (slot2FactTime.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2FTime.chr, 0x800*512+485) slot2FTime = slot2FactTime.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot2FTime.chr, 0x800*512+484) end def setSlot2Boot0Ver( slot2Boot0Ver ) slot2B0Ver = (slot2Boot0Ver.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2B0Ver.chr, 0x800*512+491) slot2B0Ver = (slot2Boot0Ver.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2B0Ver.chr, 0x800*512+490) slot2B0Ver = (slot2Boot0Ver.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2B0Ver.chr, 0x800*512+489) slot2B0Ver = slot2Boot0Ver.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot2B0Ver.chr, 0x800*512+488) end def setSlot2Boot0Date( slot2Boot0Date ) slot2B0Date = (slot2Boot0Date.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2B0Date.chr, 0x800*512+495) slot2B0Date = (slot2Boot0Date.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2B0Date.chr, 0x800*512+494) slot2B0Date = (slot2Boot0Date.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2B0Date.chr, 0x800*512+493) slot2B0Date = slot2Boot0Date.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot2B0Date.chr, 0x800*512+492) end def setSlot2Boot0Time( slot2Boot0Time ) slot2B0Time = (slot2Boot0Time.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2B0Time.chr, 0x800*512+499) slot2B0Time = (slot2Boot0Time.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2B0Time.chr, 0x800*512+498) slot2B0Time = (slot2Boot0Time.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2B0Time.chr, 0x800*512+407) slot2B0Time = slot2Boot0Time.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot2B0Time.chr, 0x800*512+496) end def setSlot2UbootVer( slot2UbootVer ) if (getHeaderVer == 0x1000000) IO.binwrite("/dev/mmcblk0", slot2UbootVer.to_s, 0x800*512+476) else slot2UVer = (slot2UbootVer.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2UVer.chr, 0x800*512+503) slot2UVer = (slot2UbootVer.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2UVer.chr, 0x800*512+502) slot2UVer = (slot2UbootVer.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2UVer.chr, 0x800*512+501) slot2UVer = slot2UbootVer.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot2UVer.chr, 0x800*512+500) end end def setSlot2UbootDate( slot2UbootDate ) if (getHeaderVer == 0x1000000) IO.binwrite("/dev/mmcblk0", slot2UbootDate.to_s, 0x800*512+492) else slot2UDate = (slot2UbootDate.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2UDate.chr, 0x800*512+507) slot2UDate = (slot2UbootDate.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2UDate.chr, 0x800*512+506) slot2UDate = (slot2UbootDate.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2UDate.chr, 0x800*512+505) slot2UDate = slot2UbootDate.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot2UDate.chr, 0x800*512+504) end end def setSlot2UbootTime( slot2UbootTime ) if (getHeaderVer == 0x1000000) IO.binwrite("/dev/mmcblk0", slot2UbootTime.to_s, 0x800*512+508) else slot2UTime = (slot2UbootTime.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2UTime.chr, 0x800*512+511) slot2UTime = (slot2UbootTime.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2UTime.chr, 0x800*512+510) slot2UTime = (slot2UbootTime.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2UTime.chr, 0x800*512+509) slot2UTime = slot2UbootTime.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot2UTime.chr, 0x800*512+508) end end def setSlot2MbrVer( slot2MbrVer ) slot2MbVer = (slot2MbrVer.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2MbVer.chr, 0x800*512+515) slot2MbVer = (slot2MbrVer.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2MbVer.chr, 0x800*512+514) slot2MbVer = (slot2MbrVer.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2MbVer.chr, 0x800*512+513) slot2MbVer = slot2MbrVer.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot2MbVer.chr, 0x800*512+512) end def setSlot2MbrDate( slot2MbrDate ) slot2MbDate = (slot2MbrDate.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2MbDate.chr, 0x800*512+519) slot2MbDate = (slot2MbrDate.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2MbDate.chr, 0x800*512+518) slot2MbDate = (slot2MbrDate.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2MbDate.chr, 0x800*512+517) slot2MbDate = slot2MbrDate.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot2MbDate.chr, 0x800*512+516) end def setSlot2MbrTime( slot2MbrTime ) slot2MbTime = (slot2MbrTime.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2MbTime.chr, 0x800*512+523) slot2MbTime = (slot2MbrTime.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2MbTime.chr, 0x800*512+522) slot2MbTime = (slot2MbrTime.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2MbTime.chr, 0x800*512+521) slot2MbTime = slot2MbrTime.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot2MbTime.chr, 0x800*512+520) end def setSlot2ResVer( slot2ResVer ) slot2RVer = (slot2ResVer.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2RVer.chr, 0x800*512+527) slot2RVer = (slot2ResVer.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2RVer.chr, 0x800*512+526) slot2RVer = (slot2ResVer.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2RVer.chr, 0x800*512+525) slot2RVer = slot2ResVer.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot2RVer.chr, 0x800*512+524) end def setSlot2ResDate( slot2ResDate ) slot2RDate = (slot2ResDate.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2RDate.chr, 0x800*512+531) slot2RDate = (slot2ResDate.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2RDate.chr, 0x800*512+530) slot2RDate = (slot2ResDate.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2RDate.chr, 0x800*512+529) slot2RDate = slot2ResDate.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot2RDate.chr, 0x800*512+528) end def setSlot2ResTime( slot2ResTime ) slot2RTime = (slot2ResTime.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2RTime.chr, 0x800*512+535) slot2RTime = (slot2ResTime.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2RTime.chr, 0x800*512+534) slot2RTime = (slot2ResTime.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2RTime.chr, 0x800*512+533) slot2RTime = slot2ResTime.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot2RTime.chr, 0x800*512+532) end def setSlot2EnvVer( slot2EnvVer ) slot2EVer = (slot2EnvVer.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2EVer.chr, 0x800*512+539) slot2EVer = (slot2EnvVer.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2EVer.chr, 0x800*512+538) slot2EVer = (slot2EnvVer.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2EVer.chr, 0x800*512+537) slot2EVer = slot2EnvVer.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot2EVer.chr, 0x800*512+536) end def setSlot2EnvDate( slot2EnvDate ) slot2EDate = (slot2EnvDate.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2EDate.chr, 0x800*512+543) slot2EDate = (slot2EnvDate.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2EDate.chr, 0x800*512+542) slot2EDate = (slot2EnvDate.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2EDate.chr, 0x800*512+541) slot2EDate = slot2EnvDate.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot2EDate.chr, 0x800*512+540) end def setSlot2EnvTime( slot2EnvTime ) slot2ETime = (slot2EnvTime.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2ETime.chr, 0x800*512+547) slot2ETime = (slot2EnvTime.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2ETime.chr, 0x800*512+546) slot2ETime = (slot2EnvTime.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2ETime.chr, 0x800*512+545) slot2ETime = slot2EnvTime.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot2ETime.chr, 0x800*512+544) end def setSlot2KernelVer( slot2KernelVer ) if (getHeaderVer == 0x1000000) IO.binwrite("/dev/mmcblk0", slot2KernelVer.to_s, 0x800*512+524) else slot2KerVer = (slot2KernelVer.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2KerVer.chr, 0x800*512+551) slot2KerVer = (slot2KernelVer.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2KerVer.chr, 0x800*512+550) slot2KerVer = (slot2KernelVer.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2KerVer.chr, 0x800*512+549) slot2KerVer = slot2KernelVer.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot2KerVer.chr, 0x800*512+548) end end def setSlot2KernelDate( slot2KernelDate ) if (getHeaderVer == 0x1000000) IO.binwrite("/dev/mmcblk0", slot2KernelDate.to_s, 0x800*512+540) else slot2KerDate = (slot2KernelDate.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2KerDate.chr, 0x800*512+555) slot2KerDate = (slot2KernelDate.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2KerDate.chr, 0x800*512+554) slot2KerDate = (slot2KernelDate.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2KerDate.chr, 0x800*512+553) slot2KerDate = slot2KernelDate.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot2KerDate.chr, 0x800*512+552) end end def setSlot2KernelTime( slot2KernelTime ) if (getHeaderVer == 0x1000000) IO.binwrite("/dev/mmcblk0", slot2KernelTime.to_s, 0x800*512+556) else slot2KerTime = (slot2KernelTime.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2KerTime.chr, 0x800*512+559) slot2KerTime = (slot2KernelTime.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2KerTime.chr, 0x800*512+558) slot2KerTime = (slot2KernelTime.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2KerTime.chr, 0x800*512+557) slot2KerTime = slot2KernelTime.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot2KerTime.chr, 0x800*512+556) end end def setSlot2VfatVer( slot2VfatVer ) slot2VfVer = (slot2VfatVer.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2VfVer.chr, 0x800*512+563) slot2VfVer = (slot2VfatVer.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2VfVer.chr, 0x800*512+562) slot2VfVer = (slot2VfatVer.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2VfVer.chr, 0x800*512+561) slot2VfVer = slot2VfatVer.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot2VfVer.chr, 0x800*512+560) end def setSlot2VfatDate( slot2VfatDate ) slot2VfDate = (slot2VfatDate.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2VfDate.chr, 0x800*512+567) slot2VfDate = (slot2VfatDate.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2VfDate.chr, 0x800*512+566) slot2VfDate = (slot2VfatDate.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2VfDate.chr, 0x800*512+565) slot2VfDate = slot2VfatDate.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot2VfDate.chr, 0x800*512+564) end def setSlot2VfatTime( slot2VfatTime ) slot2VfTime = (slot2VfatTime.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2VfTime.chr, 0x800*512+571) slot2VfTime = (slot2VfatTime.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2VfTime.chr, 0x800*512+570) slot2VfTime = (slot2VfatTime.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2VfTime.chr, 0x800*512+569) slot2VfTime = slot2VfatTime.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot2VfTime.chr, 0x800*512+568) end def setSlot2RootfsVer( slot2RootfsVer ) slot2RootVer = (slot2RootfsVer.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2RootVer.chr, 0x800*512+575) slot2RootVer = (slot2RootfsVer.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2RootVer.chr, 0x800*512+574) slot2RootVer = (slot2RootfsVer.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2RootVer.chr, 0x800*512+573) slot2RootVer = slot2RootfsVer.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot2RootVer.chr, 0x800*512+572) end def setSlot2RootfsDate( slot2RootfsDate ) slot2RootDate = (slot2RootfsDate.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2RootDate.chr, 0x800*512+579) slot2RootDate = (slot2RootfsDate.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2RootDate.chr, 0x800*512+578) slot2RootDate = (slot2RootfsDate.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2RootDate.chr, 0x800*512+577) slot2RootDate = slot2RootfsDate.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot2RootDate.chr, 0x800*512+576) end def setSlot2RootfsTime( slot2RootfsTime ) slot2RootTime = (slot2RootfsTime.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2RootTime.chr, 0x800*512+583) slot2RootTime = (slot2RootfsTime.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2RootTime.chr, 0x800*512+582) slot2RootTime = (slot2RootfsTime.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2RootTime.chr, 0x800*512+581) slot2RootTime = slot2RootfsTime.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot2RootTime.chr, 0x800*512+580) end def setSlot2AppVer( slot2AppVer ) if (getHeaderVer == 0x1000000) IO.binwrite("/dev/mmcblk0", slot2AppVer.to_s, 0x800*512+620) else slot2AVer = (slot2AppVer.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2AVer.chr, 0x800*512+391) slot2AVer = (slot2AppVer.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2AVer.chr, 0x800*512+390) slot2AVer = (slot2AppVer.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2AVer.chr, 0x800*512+389) slot2AVer = slot2AppVer.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot2AVer.chr, 0x800*512+388) end end def setSlot2AppDate( slot2AppDate ) if (getHeaderVer == 0x1000000) IO.binwrite("/dev/mmcblk0", slot2AppDate.to_s, 0x800*512+636) else slot2ADate = (slot2AppDate.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2ADate.chr, 0x800*512+395) slot2ADate = (slot2AppDate.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2ADate.chr, 0x800*512+394) slot2ADate = (slot2AppDate.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2ADate.chr, 0x800*512+393) slot2ADate = slot2AppDate.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot2ADate.chr, 0x800*512+392) end end def setSlot2AppTime( slot2AppTime ) if (getHeaderVer == 0x1000000) IO.binwrite("/dev/mmcblk0", slot2AppTime.to_s, 0x800*512+652) else slot2ATime = (slot2AppTime.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2ATime.chr, 0x800*512+399) slot2ATime = (slot2AppTime.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2ATime.chr, 0x800*512+398) slot2ATime = (slot2AppTime.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2ATime.chr, 0x800*512+397) slot2ATime = slot2AppTime.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot2ATime.chr, 0x800*512+396) end end def setSlot2M0Ver( slot2M0Ver ) if (getHeaderVer == 0x1000000) IO.binwrite("/dev/mmcblk0", slot2M0Ver.to_s, 0x800*512+572) else slot2MVer = (slot2M0Ver.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2MVer.chr, 0x800*512+403) slot2MVer = (slot2M0Ver.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2MVer.chr, 0x800*512+402) slot2MVer = (slot2M0Ver.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2MVer.chr, 0x800*512+401) slot2MVer = slot2M0Ver.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot2MVer.chr, 0x800*512+400) end end def setSlot2M0Date( slot2M0Date ) if (getHeaderVer == 0x1000000) IO.binwrite("/dev/mmcblk0", slot2M0Date.to_s, 0x800*512+588) else slot2MDate = (slot2M0Date.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2MDate.chr, 0x800*512+407) slot2MDate = (slot2M0Date.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2MDate.chr, 0x800*512+406) slot2MDate = (slot2M0Date.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2MDate.chr, 0x800*512+405) slot2MDate = slot2M0Date.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot2MDate.chr, 0x800*512+404) end end def setSlot2M0Time( slot2M0Time ) if (getHeaderVer == 0x1000000) IO.binwrite("/dev/mmcblk0", slot2M0Time.to_s, 0x800*512+604) else slot2MTime = (slot2M0Time.to_i >> 24 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2MTime.chr, 0x800*512+411) slot2MTime = (slot2M0Time.to_i >> 16 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2MTime.chr, 0x800*512+410) slot2MTime = (slot2M0Time.to_i >> 8 ) & 0xFF IO.binwrite("/dev/mmcblk0", slot2MTime.chr, 0x800*512+409) slot2MTime = slot2M0Time.to_i & 0xFF IO.binwrite("/dev/mmcblk0", slot2MTime.chr, 0x800*512+408) end end def getSysInfo( param ) if File.exists?("/dev/mmcblk0") case param when MAGIC_CODE @uMagicCode = IO.binread("/dev/mmcblk0", 4, 0x800*512) return @uMagicCode.to_s when HEADER_VER return getHeaderVer when ACTIV_SLOT @uActiveSlot4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+8) @uActiveSlot3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+9) @uActiveSlot2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+10) @uActiveSlot1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+11) @uActiveSlot = (@uActiveSlot1.ord << 24) | (@uActiveSlot2.ord << 16) | (@uActiveSlot3.ord << 8) | @uActiveSlot4.ord return @uActiveSlot.to_i when UUID @acUUID = IO.binread("/dev/mmcblk0", 40, 0x800*512+12) return @acUUID.to_s when MANUFACTER_NAME @acManufacturerName = IO.binread("/dev/mmcblk0", 32, 0x800*512+52) return @acManufacturerName.to_s when PRODUCT_NAME @acProductName = IO.binread("/dev/mmcblk0", 32, 0x800*512+84) return @acProductName.to_s when MODEL_NAME @acModelName = IO.binread("/dev/mmcblk0", 32, 0x800*512+116) return @acModelName.to_s when HARDWARE_ID @acHardwareId = IO.binread("/dev/mmcblk0", 32, 0x800*512+148) return @acHardwareId.to_s when SERIOAL_NO @acSerialNo = IO.binread("/dev/mmcblk0", 64, 0x800*512+180) return @acSerialNo.to_s when ALIAS_NAME @acAliasName = IO.binread("/dev/mmcblk0", 32, 0x800*512+244) return @acAliasName.to_s when SLOT1_SUCCESS @usSlot1Success2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+276) @usSlot1Success1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+277) @usSlot1Success = (@usSlot1Success1.ord << 8) | @usSlot1Success2.ord return @usSlot1Success.to_i when SLOT1_FAIL_CNT @usSlot1FailCnt2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+278) @usSlot1FailCnt1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+279) @usSlot1FailCnt = (@usSlot1FailCnt1.ord << 8) | @usSlot1FailCnt2.ord return @usSlot1FailCnt.to_i when SLOT1_FACT_VER @uSlot1FactVer4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+280) @uSlot1FactVer3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+281) @uSlot1FactVer4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+282) @uSlot1FactVer1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+283) @uSlot1FactVer = (@uSlot1FactVer4.ord << 24) | (@uSlot1FactVer3.ord << 16) | (@uSlot1FactVer2.ord << 8) | @uSlot1FactVer1.ord return @uSlot1FactVer.to_i when SLOT1_FACT_DATE @uSlot1FactDate4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+284) @uSlot1FactDate3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+285) @uSlot1FactDate2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+286) @uSlot1FactDate1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+287) @uSlot1FactDate = (@uSlot1FactDate4.ord << 24) | (@uSlot1FactDate3.ord << 16) | (@uSlot1FactDate2.ord << 8) | @uSlot1FactDate1.ord return @uSlot1FactDate.to_i when SLOT1_FACT_TIME @uSlot1FactTime4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+288) @uSlot1FactTime3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+289) @uSlot1FactTime2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+290) @uSlot1FactTime1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+291) @uSlot1FactTime = (@uSlot1FactTime4.ord << 24) | (@uSlot1FactTime3.ord << 16) | (@uSlot1FactTime2.ord << 8) | @uSlot1FactTime1.ord return @uSlot1FactTime.to_i when SLOT1_BOOT0_VER @uSlot1Boot0Ver4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+292) @uSlot1Boot0Ver3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+293) @uSlot1Boot0Ver2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+294) @uSlot1Boot0Ver1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+295) @uSlot1Boot0Ver = (@uSlot1Boot0Ver4.ord << 24) | (@uSlot1Boot0Ver3.ord << 16) | (@uSlot1Boot0Ver2.ord << 8) | @uSlot1Boot0Ver1.ord return @uSlot1Boot0Ver.to_i when SLOT1_BOOT0_DATE @uSlot1Boot0Date4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+296) @uSlot1Boot0Date3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+297) @uSlot1Boot0Date2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+298) @uSlot1Boot0Date1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+299) @uSlot1Boot0Date = (@uSlot1Boot0Date4.ord << 24) | (@uSlot1Boot0Date3.ord << 16) | (@uSlot1Boot0Date2.ord << 8) | @uSlot1Boot0Date1.ord return @uSlot1Boot0Date.to_i when SLOT1_BOOT0_TIME @uSlot1Boot0Time4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+300) @uSlot1Boot0Time2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+301) @uSlot1Boot0Time2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+302) @uSlot1Boot0Time1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+303) @uSlot1Boot0Time = (@uSlot1Boot0Time4.ord << 24) | (@uSlot1Boot0Time3.ord << 16) | (@uSlot1Boot0Time2.ord << 8) | @uSlot1Boot0Time1.ord return @uSlot1Boot0Time.to_i when SLOT1_UBOOT_VER if (getHeaderVer == 0x1000000) @acSlot1UbootVer = IO.binread("/dev/mmcblk0", 16, 0x800*512+280) return @acSlot1UbootVer.to_s else @acSlot1UbootVer4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+304) @acSlot1UbootVer3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+305) @acSlot1UbootVer2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+306) @acSlot1UbootVer1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+307) @acSlot1UbootVer = (@acSlot1UbootVer4.ord << 24) | (@acSlot1UbootVer3.ord << 16) | (@acSlot1UbootVer2.ord << 8) | @acSlot1UbootVer1.ord return @acSlot1UbootVer.to_i end when SLOT1_UBOOT_DATE if (getHeaderVer == 0x1000000) @acSlot1UbootDate = IO.binread("/dev/mmcblk0", 16, 0x800*512+296) return @acSlot1UbootDate.to_s else @acSlot1UbootDate4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+308) @acSlot1UbootDate3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+309) @acSlot1UbootDate2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+310) @acSlot1UbootDate1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+311) @acSlot1UbootDate = (@acSlot1UbootDate4.ord << 24) | (@acSlot1UbootDate3.ord << 16) | (@acSlot1UbootDate2.ord << 8) | @acSlot1UbootDate1.ord return @acSlot1UbootDate.to_i end when SLOT1_UBOOT_TIME if (getHeaderVer == 0x1000000) @acSlot1UbootTime = IO.binread("/dev/mmcblk0", 16, 0x800*512+312) return @acSlot1UbootTime.to_s else @acSlot1UbootTime4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+312) @acSlot1UbootTime3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+313) @acSlot1UbootTime2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+314) @acSlot1UbootTime1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+315) @acSlot1UbootTime = (@acSlot1UbootTime4.ord << 24) | (@acSlot1UbootTime3.ord << 16) | (@acSlot1UbootTime2.ord << 8) | @acSlot1UbootTime1.ord return @acSlot1UbootTime.to_i end when SLOT1_MBR_VER @uSlot1MbrVer4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+316) @uSlot1MbrVer3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+317) @uSlot1MbrVer2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+318) @uSlot1MbrVer1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+319) @uSlot1MbrVer = (@uSlot1MbrVer4.ord << 24) | (@uSlot1MbrVer3.ord << 16) | (@uSlot1MbrVer2.ord << 8) | @uSlot1MbrVer1.ord return @uSlot1MbrVer.to_i when SLOT1_MBR_DATE @uSlot1MbrDate4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+320) @uSlot1MbrDate3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+321) @uSlot1MbrDate2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+322) @uSlot1MbrDate1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+323) @uSlot1MbrDate = (@uSlot1MbrDate4.ord << 24) | (@uSlot1MbrDate3.ord << 16) | (@uSlot1MbrDate2.ord << 8) | @uSlot1MbrDate1.ord return @uSlot1MbrDate.to_i when SLOT1_MBR_TIME @uSlot1MbrTime4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+324) @uSlot1MbrTime3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+325) @uSlot1MbrTime2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+326) @uSlot1MbrTime1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+327) @uSlot1MbrTime = (@uSlot1MbrTime4.ord << 24) | (@uSlot1MbrTime3.ord << 16) | (@uSlot1MbrTime2.ord << 8) | @uSlot1MbrTime1.ord return @uSlot1MbrTime.to_i when SLOT1_RES_VER @uSlot1ResVer4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+328) @uSlot1ResVer3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+329) @uSlot1ResVer2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+330) @uSlot1ResVer1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+331) @uSlot1ResVer = (@uSlot1ResVer4.ord << 24) | (@uSlot1ResVer3.ord << 16) | (@uSlot1ResVer2.ord << 8) | @uSlot1ResVer1.ord return @uSlot1ResVer.to_i when SLOT1_RES_DATE @uSlot1ResDate4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+332) @uSlot1ResDate3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+333) @uSlot1ResDate2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+334) @uSlot1ResDate1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+335) @uSlot1MbrDate = (@uSlot1ResDate4.ord << 24) | (@uSlot1ResDate3.ord << 16) | (@uSlot1ResDate2.ord << 8) | @uSlot1ResDate1.ord return @uSlot1ResDate.to_i when SLOT1_RES_TIME @uSlot1ResTime4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+336) @uSlot1ResTime3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+337) @uSlot1ResTime2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+338) @uSlot1ResTime1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+339) @uSlot1ResTime = (@uSlot1ResTime4.ord << 24) | (@uSlot1ResTime3.ord << 16) | (@uSlot1ResTime2.ord << 8) | @uSlot1ResTime1.ord return @uSlot1ResTime.to_i when SLOT1_ENV_VER @uSlot1EnvVer4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+340) @uSlot1EnvVer3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+341) @uSlot1EnvVer2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+342) @uSlot1EnvVer1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+343) @uSlot1EnvVer = (@uSlot1EnvVer4.ord << 24) | (@uSlot1EnvVer3.ord << 16) | (@uSlot1EnvVer2.ord << 8) | @uSlot1EnvVer1.ord return @uSlot1EnvVer.to_i when SLOT1_ENV_DATE @uSlot1EnvDate4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+344) @uSlot1EnvDate3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+345) @uSlot1EnvDate2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+346) @uSlot1EnvDate1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+347) @uSlot1EnvDate = (@uSlot1EnvDate4.ord << 24) | (@uSlot1EnvDate3.ord << 16) | (@uSlot1EnvDate2.ord << 8) | @uSlot1EnvDate1.ord return @uSlot1EnvDate.to_i when SLOT1_ENV_TIME @uSlot1EnvTime4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+348) @uSlot1EnvTime3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+349) @uSlot1EnvTime2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+350) @uSlot1EnvTime1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+351) @uSlot1EnvTime = (@uSlot1EnvTime4.ord << 24) | (@uSlot1EnvTime3.ord << 16) | (@uSlot1EnvTime2.ord << 8) | @uSlot1EnvTime1.ord return @uSlot1EnvTime.to_i when SLOT1_KERNEL_VER if (getHeaderVer == 0x1000000) @acSlot1KernelVer = IO.binread("/dev/mmcblk0", 16, 0x800*512+328) return @acSlot1KernelVer.to_s else @acSlot1KernelVer4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+352) @acSlot1KernelVer3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+353) @acSlot1KernelVer2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+354) @acSlot1KernelVer1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+355) @acSlot1KernelVer = (@acSlot1KernelVer4.ord << 24) | (@acSlot1KernelVer3.ord << 16) | (@acSlot1KernelVer2.ord << 8) | @acSlot1KernelVer1.ord return @acSlot1KernelVer.to_i end when SLOT1_KERNEL_DATE if (getHeaderVer == 0x1000000) @acSlot1KernelDate = IO.binread("/dev/mmcblk0", 16, 0x800*512+344) return @acSlot1KernelDate.to_s else @acSlot1KernelDate4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+356) @acSlot1KernelDate3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+357) @acSlot1KernelDate2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+358) @acSlot1KernelDate1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+359) @acSlot1KernelDate = (@acSlot1KernelDate4.ord << 24) | (@acSlot1KernelDate3.ord << 16) | (@acSlot1KernelDate2.ord << 8) | @acSlot1KernelDate1.ord return @acSlot1KernelDate.to_i end when SLOT1_KERNEL_TIME if (getHeaderVer == 0x1000000) @acSlot1KernelTime = IO.binread("/dev/mmcblk0", 16, 0x800*512+360) return @acSlot1KernelTime.to_s else @acSlot1KernelTime4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+360) @acSlot1KernelTime3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+361) @acSlot1KernelTime2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+362) @acSlot1KernelTime1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+363) @acSlot1KernelTime = (@acSlot1KernelTime4.ord << 24) | (@acSlot1KernelTime3.ord << 16) | (@acSlot1KernelTime2.ord << 8) | @acSlot1KernelTime1.ord return @acSlot1KernelTime.to_i end when SLOT1_VFAT_VER @uSlot1VfatVer4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+364) @uSlot1VfatVer3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+365) @uSlot1VfatVer2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+366) @uSlot1VfatVer1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+367) @uSlot1VfatVer = (@uSlot1VfatVer4.ord << 24) | (@uSlot1VfatVer3.ord << 16) | (@uSlot1VfatVer2.ord << 8) | @uSlot1VfatVer1.ord return @uSlot1VfatVer.to_i when SLOT1_VFAT_DATE @uSlot1VfatDate4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+368) @uSlot1VfatDate3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+369) @uSlot1VfatDate2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+370) @uSlot1VfatDate1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+371) @uSlot1VfatDate = (@uSlot1VfatDate4.ord << 24) | (@uSlot1VfatDate3.ord << 16) | (@uSlot1VfatDate2.ord << 8) | @uSlot1VfatDate1.ord return @uSlot1VfatDate.to_i when SLOT1_VFAT_TIME @uSlot1VfatTime4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+372) @uSlot1VfatTime3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+373) @uSlot1VfatTime2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+374) @uSlot1VfatTime1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+375) @uSlot1VfatTime = (@uSlot1VfatTime4.ord << 24) | (@uSlot1VfatTime3.ord << 16) | (@uSlot1VfatTime2.ord << 8) | @uSlot1VfatTime1.ord return @uSlot1VfatTime.to_i when SLOT1_ROOTFS_VER @uSlot1RootFsVer4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+376) @uSlot1RootFsVer3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+377) @uSlot1RootFsVer2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+378) @uSlot1RootFsVer1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+379) @uSlot1RootFsVer = (@uSlot1RootFsVer4.ord << 24) | (@uSlot1RootFsVer3.ord << 16) | (@uSlot1RootFsVer2.ord << 8) | @uSlot1RootFsVer1.ord return @uSlot1RootFsVer.to_i when SLOT1_ROOTFS_DATE @uSlot1RootFsDate4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+380) @uSlot1RootFsDate3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+381) @uSlot1RootFsDate2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+382) @uSlot1RootFsDate1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+383) @uSlot1RootFsDate = (@uSlot1RootFsDate4.ord << 24) | (@uSlot1RootFsDate3.ord << 16) | (@uSlot1RootFsDate2.ord << 8) | @uSlot1RootFsDate1.ord return @uSlot1RootFsDate.to_i when SLOT1_ROOTFS_TIME @uSlot1RootFsTime4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+384) @uSlot1RootFsTime3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+385) @uSlot1RootFsTime2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+386) @uSlot1RootFsTime1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+387) @uSlot1RootFsTime = (@uSlot1RootFsTime4.ord << 24) | (@uSlot1RootFsTime3.ord << 16) | (@uSlot1RootFsTime2.ord << 8) | @uSlot1RootFsTime1.ord return @uSlot1RootFsTime.to_i when SLOT1_APP_VER if (getHeaderVer == 0x1000000) @acSlot1AppVer = IO.binread("/dev/mmcblk0", 16, 0x800*512+424) return @acSlot1AppVer.to_s else @acSlot1AppVer4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+388) @acSlot1AppVer3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+389) @acSlot1AppVer2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+390) @acSlot1AppVer1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+391) @acSlot1AppVer = (@acSlot1AppVer4.ord << 24) | (@acSlot1AppVer3.ord << 16) | (@acSlot1AppVer2.ord << 8) | @acSlot1AppVer1.ord return @acSlot1AppVer.to_i end when SLOT1_APP_DATE if (getHeaderVer == 0x1000000) @acSlot1AppDate = IO.binread("/dev/mmcblk0", 16, 0x800*512+440) return @acSlot1AppDate.to_s else @acSlot1AppDate4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+392) @acSlot1AppDate3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+393) @acSlot1AppDate2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+394) @acSlot1AppDate1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+395) @acSlot1AppDate = (@acSlot1AppDate4.ord << 24) | (@acSlot1AppDate3.ord << 16) | (@acSlot1AppDate2.ord << 8) | @acSlot1AppDate1.ord return @acSlot1AppDate.to_i end when SLOT1_APP_TIME if (getHeaderVer == 0x1000000) @acSlot1AppTime = IO.binread("/dev/mmcblk0", 16, 0x800*512+456) return @acSlot1AppTime.to_s else @acSlot1AppTime4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+396) @acSlot1AppTime3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+397) @acSlot1AppTime2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+398) @acSlot1AppTime1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+399) @acSlot1AppTime = (@acSlot1AppTime4.ord << 24) | (@acSlot1AppTime3.ord << 16) | (@acSlot1AppTime2.ord << 8) | @acSlot1AppTime1.ord return @acSlot1AppTime.to_i end when SLOT1_M0_VER if (getHeaderVer == 0x1000000) @acSlot1M0Ver = IO.binread("/dev/mmcblk0", 16, 0x800*512+376) return @acSlot1M0Ver.to_s else @acSlot1M0Ver4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+400) @acSlot1M0Ver3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+401) @acSlot1M0Ver2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+402) @acSlot1M0Ver1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+403) @acSlot1M0Ver = (@acSlot1M0Ver4.ord << 24) | (@acSlot1M0Ver3.ord << 16) | (@acSlot1M0Ver2.ord << 8) | @acSlot1M0Ver1.ord return @acSlot1M0Ver.to_i end when SLOT1_M0_DATE if (getHeaderVer == 0x1000000) @acSlot1M0Date = IO.binread("/dev/mmcblk0", 16, 0x800*512+392) return @acSlot1M0Date.to_s else @acSlot1M0Date4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+404) @acSlot1M0Date3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+405) @acSlot1M0Date2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+406) @acSlot1M0Date1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+407) @acSlot1M0Date = (@acSlot1M0Date4.ord << 24) | (@acSlot1M0Date3.ord << 16) | (@acSlot1M0Date2.ord << 8) | @acSlot1M0Date1.ord return @acSlot1M0Date.to_i end when SLOT1_M0_TIME if (getHeaderVer == 0x1000000) @acSlot1M0Time = IO.binread("/dev/mmcblk0", 16, 0x800*512+408) return @acSlot1M0Time.to_s else @acSlot1M0Time4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+408) @acSlot1M0Time3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+409) @acSlot1M0Time2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+410) @acSlot1M0Time1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+411) @acSlot1M0Time = (@acSlot1M0Time4.ord << 24) | (@acSlot1M0Time3.ord << 16) | (@acSlot1M0Time2.ord << 8) | @acSlot1M0Time1.ord return @acSlot1M0Time.to_i end when SLOT2_SUCCESS if (getHeaderVer == 0x1000000) @usSlot2Success2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+472) @usSlot2Success1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+473) else @usSlot2Success2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+412) @usSlot2Success1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+413) end @usSlot2Success = (@usSlot2Success1.ord << 8) | @usSlot2Success2.ord return @usSlot2Success.to_i when SLOT2_FAIL_CNT if (getHeaderVer == 0x1000000) @usSlot2FailCnt2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+474) @usSlot2FailCnt1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+475) else @usSlot2FailCnt2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+414) @usSlot2FailCnt1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+415) end @usSlot2FailCnt = (@usSlot2FailCnt1.ord << 8) | @usSlot2FailCnt2.ord return @usSlot2FailCnt.to_i when SLOT2_FACT_VER @uSlot2FactVer4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+416) @uSlot2FactVer3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+417) @uSlot2FactVer4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+418) @uSlot2FactVer1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+419) @uSlot2FactVer = (@uSlot2FactVer4.ord << 24) | (@uSlot2FactVer3.ord << 16) | (@uSlot2FactVer2.ord << 8) | @uSlot2FactVer1.ord return @uSlot2FactVer.to_i when SLOT2_FACT_DATE @uSlot2FactDate4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+420) @uSlot2FactDate3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+421) @uSlot2FactDate2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+422) @uSlot2FactDate1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+423) @uSlot2FactDate = (@uSlot2FactDate4.ord << 24) | (@uSlot2FactDate3.ord << 16) | (@uSlot2FactDate2.ord << 8) | @uSlot2FactDate1.ord return @uSlot2FactDate.to_i when SLOT2_FACT_TIME @uSlot2FactTime4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+424) @uSlot2FactTime3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+425) @uSlot2FactTime2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+426) @uSlot2FactTime1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+427) @uSlot2FactTime = (@uSlot2FactTime4.ord << 24) | (@uSlot2FactTime3.ord << 16) | (@uSlot2FactTime2.ord << 8) | @uSlot2FactTime1.ord return @uSlot2FactTime.to_i when SLOT2_BOOT0_VER @uSlot2Boot0Ver4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+428) @uSlot2Boot0Ver3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+429) @uSlot2Boot0Ver2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+430) @uSlot2Boot0Ver1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+431) @uSlot2Boot0Ver = (@uSlot2Boot0Ver4.ord << 24) | (@uSlot2Boot0Ver3.ord << 16) | (@uSlot2Boot0Ver2.ord << 8) | @uSlot2Boot0Ver1.ord return @uSlot2Boot0Ver.to_i when SLOT2_BOOT0_DATE @uSlot2Boot0Date4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+432) @uSlot2Boot0Date3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+433) @uSlot2Boot0Date2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+434) @uSlot2Boot0Date1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+435) @uSlot2Boot0Date = (@uSlot2Boot0Date4.ord << 24) | (@uSlot2Boot0Date3.ord << 16) | (@uSlot2Boot0Date2.ord << 8) | @uSlot2Boot0Date1.ord return @uSlot2Boot0Date.to_i when SLOT2_BOOT0_TIME @uSlot2Boot0Time4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+436) @uSlot2Boot0Time2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+437) @uSlot2Boot0Time2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+438) @uSlot2Boot0Time1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+439) @uSlot2Boot0Time = (@uSlot2Boot0Time4.ord << 24) | (@uSlot2Boot0Time3.ord << 16) | (@uSlot2Boot0Time2.ord << 8) | @uSlot2Boot0Time1.ord return @uSlot2Boot0Time.to_i when SLOT2_UBOOT_VER if (getHeaderVer == 0x1000000) @acSlot2UbootVer = IO.binread("/dev/mmcblk0", 16, 0x800*512+476) return @acSlot2UbootVer.to_s else @acSlot2UbootVer4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+440) @acSlot2UbootVer3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+441) @acSlot2UbootVer2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+442) @acSlot2UbootVer1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+443) @acSlot2UbootVer = (@acSlot2UbootVer4.ord << 24) | (@acSlot2UbootVer3.ord << 16) | (@acSlot2UbootVer2.ord << 8) | @acSlot2UbootVer1.ord return @acSlot2UbootVer.to_i end when SLOT2_UBOOT_DATE if (getHeaderVer == 0x1000000) @acSlot2UbootDate = IO.binread("/dev/mmcblk0", 16, 0x800*512+492) return @acSlot2UbootDate.to_s else @acSlot2UbootDate4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+444) @acSlot2UbootDate3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+445) @acSlot2UbootDate2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+446) @acSlot2UbootDate1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+447) @acSlot2UbootDate = (@acSlot2UbootDate4.ord << 24) | (@acSlot2UbootDate3.ord << 16) | (@acSlot2UbootDate2.ord << 8) | @acSlot2UbootDate1.ord return @acSlot1UbootDate.to_i end when SLOT2_UBOOT_TIME if (getHeaderVer == 0x1000000) @acSlot2UbootTime = IO.binread("/dev/mmcblk0", 16, 0x800*512+508) return @acSlot2UbootTime.to_s else @acSlot2UbootTime4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+448) @acSlot2UbootTime3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+449) @acSlot2UbootTime2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+450) @acSlot2UbootTime1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+451) @acSlot2UbootTime = (@acSlot2UbootTime4.ord << 24) | (@acSlot2UbootTime3.ord << 16) | (@acSlot2UbootTime2.ord << 8) | @acSlot2UbootTime1.ord return @acSlot2UbootTime.to_i end when SLOT2_MBR_VER @uSlot2MbrVer4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+452) @uSlot2MbrVer3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+453) @uSlot2MbrVer2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+454) @uSlot2MbrVer1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+455) @uSlot2MbrVer = (@uSlot2MbrVer4.ord << 24) | (@uSlot2MbrVer3.ord << 16) | (@uSlot2MbrVer2.ord << 8) | @uSlot2MbrVer1.ord return @uSlot2MbrVer.to_i when SLOT2_MBR_DATE @uSlot2MbrDate4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+456) @uSlot2MbrDate3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+457) @uSlot2MbrDate2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+458) @uSlot2MbrDate1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+459) @uSlot2MbrDate = (@uSlot2MbrDate4.ord << 24) | (@uSlot2MbrDate3.ord << 16) | (@uSlot2MbrDate2.ord << 8) | @uSlot2MbrDate1.ord return @uSlot2MbrDate.to_i when SLOT2_MBR_TIME @uSlot2MbrTime4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+460) @uSlot2MbrTime3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+461) @uSlot2MbrTime2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+462) @uSlot2MbrTime1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+463) @uSlot2MbrTime = (@uSlot2MbrTime4.ord << 24) | (@uSlot2MbrTime3.ord << 16) | (@uSlot2MbrTime2.ord << 8) | @uSlot2MbrTime1.ord return @uSlot2MbrTime.to_i when SLOT2_RES_VER @uSlot2ResVer4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+464) @uSlot2ResVer3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+465) @uSlot2ResVer2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+466) @uSlot2ResVer1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+467) @uSlot2ResVer = (@uSlot2ResVer4.ord << 24) | (@uSlot2ResVer3.ord << 16) | (@uSlot2ResVer2.ord << 8) | @uSlot2ResVer1.ord return @uSlot2ResVer.to_i when SLOT2_RES_DATE @uSlot2ResDate4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+468) @uSlot2ResDate3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+469) @uSlot2ResDate2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+470) @uSlot2ResDate1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+471) @uSlot2MbrDate = (@uSlot2ResDate4.ord << 24) | (@uSlot2ResDate3.ord << 16) | (@uSlot2ResDate2.ord << 8) | @uSlot2ResDate1.ord return @uSlot2ResDate.to_i when SLOT2_RES_TIME @uSlot2ResTime4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+472) @uSlot2ResTime3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+473) @uSlot2ResTime2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+474) @uSlot2ResTime1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+475) @uSlot2ResTime = (@uSlot2ResTime4.ord << 24) | (@uSlot2ResTime3.ord << 16) | (@uSlot2ResTime2.ord << 8) | @uSlot2ResTime1.ord return @uSlot2ResTime.to_i when SLOT2_ENV_VER @uSlot2EnvVer4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+476) @uSlot2EnvVer3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+477) @uSlot2EnvVer2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+478) @uSlot2EnvVer1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+479) @uSlot2EnvVer = (@uSlot2EnvVer4.ord << 24) | (@uSlot2EnvVer3.ord << 16) | (@uSlot2EnvVer2.ord << 8) | @uSlot2EnvVer1.ord return @uSlot2EnvVer.to_i when SLOT2_ENV_DATE @uSlot2EnvDate4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+480) @uSlot2EnvDate3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+481) @uSlot2EnvDate2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+482) @uSlot2EnvDate1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+483) @uSlot2EnvDate = (@uSlot2EnvDate4.ord << 24) | (@uSlot2EnvDate3.ord << 16) | (@uSlot2EnvDate2.ord << 8) | @uSlot2EnvDate1.ord return @uSlot2EnvDate.to_i when SLOT2_ENV_TIME @uSlot2EnvTime4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+484) @uSlot2EnvTime3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+485) @uSlot2EnvTime2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+486) @uSlot2EnvTime1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+487) @uSlot2EnvTime = (@uSlot2EnvTime4.ord << 24) | (@uSlot2EnvTime3.ord << 16) | (@uSlot2EnvTime2.ord << 8) | @uSlot2EnvTime1.ord return @uSlot1EnvTime.to_i when SLOT2_KERNEL_VER if (getHeaderVer == 0x1000000) @acSlot2KernelVer = IO.binread("/dev/mmcblk0", 16, 0x800*512+524) return @acSlot2KernelVer.to_s else @acSlot2KernelVer4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+488) @acSlot2KernelVer3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+489) @acSlot2KernelVer2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+490) @acSlot2KernelVer1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+491) @acSlot2KernelVer = (@acSlot2KernelVer4.ord << 24) | (@acSlot2KernelVer3.ord << 16) | (@acSlot2KernelVer2.ord << 8) | @acSlot2KernelVer1.ord return @acSlot1KernelVer.to_i end when SLOT2_KERNEL_DATE if (getHeaderVer == 0x1000000) @acSlot2KernelDate = IO.binread("/dev/mmcblk0", 16, 0x800*512+540) return @acSlot2KernelDate.to_s else @acSlot2KernelDate4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+492) @acSlot2KernelDate3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+493) @acSlot2KernelDate2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+494) @acSlot2KernelDate1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+495) @acSlot2KernelDate = (@acSlot2KernelDate4.ord << 24) | (@acSlot2KernelDate3.ord << 16) | (@acSlot2KernelDate2.ord << 8) | @acSlot2KernelDate1.ord return @acSlot2KernelDate.to_i end when SLOT2_KERNEL_TIME if (getHeaderVer == 0x1000000) @acSlot2KernelTime = IO.binread("/dev/mmcblk0", 16, 0x800*512+556) return @acSlot2KernelTime.to_s else @acSlot2KernelTime4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+496) @acSlot2KernelTime3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+497) @acSlot2KernelTime2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+498) @acSlot2KernelTime1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+499) @acSlot2KernelTime = (@acSlot2KernelTime4.ord << 24) | (@acSlot2KernelTime3.ord << 16) | (@acSlot2KernelTime2.ord << 8) | @acSlot2KernelTime1.ord return @acSlot2KernelTime.to_i end when SLOT2_VFAT_VER @uSlot2VfatVer4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+500) @uSlot2VfatVer3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+501) @uSlot2VfatVer2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+502) @uSlot2VfatVer1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+503) @uSlot2VfatVer = (@uSlot2VfatVer4.ord << 24) | (@uSlot2VfatVer3.ord << 16) | (@uSlot2VfatVer2.ord << 8) | @uSlot2VfatVer1.ord return @uSlot2VfatVer.to_i when SLOT2_VFAT_DATE @uSlot2VfatDate4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+504) @uSlot2VfatDate3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+505) @uSlot2VfatDate2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+506) @uSlot2VfatDate1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+507) @uSlot2VfatDate = (@uSlot2VfatDate4.ord << 24) | (@uSlot2VfatDate3.ord << 16) | (@uSlot2VfatDate2.ord << 8) | @uSlot2VfatDate1.ord return @uSlot2VfatDate.to_i when SLOT2_VFAT_TIME @uSlot2VfatTime4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+508) @uSlot2VfatTime3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+509) @uSlot2VfatTime2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+510) @uSlot2VfatTime1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+511) @uSlot2VfatTime = (@uSlot2VfatTime4.ord << 24) | (@uSlot2VfatTime3.ord << 16) | (@uSlot2VfatTime2.ord << 8) | @uSlot2VfatTime1.ord return @uSlot2VfatTime.to_i when SLOT2_ROOTFS_VER @uSlot2RootFsVer4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+512) @uSlot2RootFsVer3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+513) @uSlot2RootFsVer2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+514) @uSlot2RootFsVer1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+515) @uSlot2RootFsVer = (@uSlot2RootFsVer4.ord << 24) | (@uSlot2RootFsVer3.ord << 16) | (@uSlot2RootFsVer2.ord << 8) | @uSlot2RootFsVer1.ord return @uSlot2RootFsVer.to_i when SLOT2_ROOTFS_DATE @uSlot2RootFsDate4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+516) @uSlot2RootFsDate3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+517) @uSlot2RootFsDate2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+518) @uSlot2RootFsDate1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+519) @uSlot2RootFsDate = (@uSlot2RootFsDate4.ord << 24) | (@uSlot2RootFsDate3.ord << 16) | (@uSlot2RootFsDate2.ord << 8) | @uSlot2RootFsDate1.ord return @uSlot2RootFsDate.to_i when SLOT2_ROOTFS_TIME @uSlot2RootFsTime4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+520) @uSlot2RootFsTime3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+521) @uSlot2RootFsTime2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+522) @uSlot2RootFsTime1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+523) @uSlot2RootFsTime = (@uSlot2RootFsTime4.ord << 24) | (@uSlot2RootFsTime3.ord << 16) | (@uSlot2RootFsTime2.ord << 8) | @uSlot2RootFsTime1.ord return @uSlot2RootFsTime.to_i when SLOT2_APP_VER if (getHeaderVer == 0x1000000) @acSlot2AppVer = IO.binread("/dev/mmcblk0", 16, 0x800*512+620) return @acSlot2AppVer.to_s else @acSlot2AppVer4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+524) @acSlot2AppVer3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+525) @acSlot2AppVer2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+526) @acSlot2AppVer1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+527) @acSlot2AppVer = (@acSlot2AppVer4.ord << 24) | (@acSlot2AppVer3.ord << 16) | (@acSlot2AppVer2.ord << 8) | @acSlot2AppVer1.ord return @acSlot2AppVer.to_i end when SLOT2_APP_DATE if (getHeaderVer == 0x1000000) @acSlot2AppDate = IO.binread("/dev/mmcblk0", 16, 0x800*512+636) return @acSlot2AppDate.to_s else @acSlot2AppDate4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+528) @acSlot2AppDate3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+529) @acSlot2AppDate2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+530) @acSlot2AppDate1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+531) @acSlot2AppDate = (@acSlot2AppDate4.ord << 24) | (@acSlot2AppDate3.ord << 16) | (@acSlot2AppDate2.ord << 8) | @acSlot2AppDate1.ord return @acSlot2AppDate.to_i end when SLOT2_APP_TIME if (getHeaderVer == 0x1000000) @acSlot2AppTime = IO.binread("/dev/mmcblk0", 16, 0x800*512+652) return @acSlot2AppTime.to_s else @acSlot2AppTime4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+532) @acSlot2AppTime3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+533) @acSlot2AppTime2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+534) @acSlot2AppTime1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+535) @acSlot2AppTime = (@acSlot2AppTime4.ord << 24) | (@acSlot2AppTime3.ord << 16) | (@acSlot2AppTime2.ord << 8) | @acSlot2AppTime1.ord return @acSlot2AppTime.to_i end when SLOT2_M0_VER if (getHeaderVer == 0x1000000) @acSlot2M0Ver = IO.binread("/dev/mmcblk0", 16, 0x800*512+572) return @acSlot2M0Ver.to_s else @acSlot2M0Ver4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+536) @acSlot2M0Ver3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+537) @acSlot2M0Ver2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+538) @acSlot2M0Ver1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+539) @acSlot2M0Ver = (@acSlot2M0Ver4.ord << 24) | (@acSlot2M0Ver3.ord << 16) | (@acSlot2M0Ver2.ord << 8) | @acSlot2M0Ver1.ord return @acSlot2M0Ver.to_i end when SLOT2_M0_DATE if (getHeaderVer == 0x1000000) @acSlot2M0Date = IO.binread("/dev/mmcblk0", 16, 0x800*512+588) return @acSlot2M0Date.to_s else @acSlot2M0Date4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+540) @acSlot2M0Date3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+541) @acSlot2M0Date2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+542) @acSlot2M0Date1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+543) @acSlot2M0Date = (@acSlot2M0Date4.ord << 24) | (@acSlot2M0Date3.ord << 16) | (@acSlot2M0Date2.ord << 8) | @acSlot2M0Date1.ord return @acSlot2M0Date.to_i end when SLOT2_M0_TIME if (getHeaderVer == 0x1000000) @acSlot2M0Time = IO.binread("/dev/mmcblk0", 16, 0x800*512+604) return @acSlot2M0Time.to_s else @acSlot2M0Time4 = IO.binread("/dev/mmcblk0", 1, 0x800*512+544) @acSlot2M0Time3 = IO.binread("/dev/mmcblk0", 1, 0x800*512+545) @acSlot2M0Time2 = IO.binread("/dev/mmcblk0", 1, 0x800*512+546) @acSlot2M0Time1 = IO.binread("/dev/mmcblk0", 1, 0x800*512+547) @acSlot2M0Time = (@acSlot2M0Time4.ord << 24) | (@acSlot2M0Time3.ord << 16) | (@acSlot2M0Time2.ord << 8) | @acSlot2M0Time1.ord return @acSlot2M0Time.to_i end end end end def setSysInfo( param, data ) if File.exists?("/dev/mmcblk0") case param when MAGIC_CODE setMagicCode( data ) when HEADER_VER setHeaderVer( data ) when ACTIV_SLOT setActiveSlot( data ) when UUID setUUID( data ) when MANUFACTER_NAME setManufacturerName( data ) when PRODUCT_NAME setProductName( data ) when MODEL_NAME setModelName( data ) when HARDWARE_ID setHardwareId( data ) when SERIAL_NO setSerialNo( data ) when ALIAS_NAME setAliasName( data ) when SLOT1_SUCCESS setSlot1Success( data ) when SLOT1_FAIL_CNT setSlot1FailCnt( data ) when SLOT1_FACT_VER setSlot1FactVer( data ) when SLOT1_FACT_DATE setSlot1FactDate( data ) when SLOT1_FACT_TIME setSlot1FactTime( data ) when SLOT1_BOOT0_VER setSlot1Boot0Ver( data ) when SLOT1_BOOT0_DATE setSlot1Boot0Date( data ) when SLOT1_BOOT0_TIME setSlot1Boot0Time( data ) when SLOT1_UBOOT_VER setSlot1UbootVer( data ) when SLOT1_UBOOT_DATE setSlot1UbootDate( data ) when SLOT1_UBOOT_TIME setSlot1UbootTime( data ) when SLOT1_MBR_VER setSlot1MbrVer( data ) when SLOT1_MBR_DATE setSlot1MbrDate( data ) when SLOT1_MBR_TIME setSlot1MbrTime( data ) when SLOT1_RES_VER setSlot1ResVer( data ) when SLOT1_RES_DATE setSlot1ResDate( data ) when SLOT1_RES_TIME setSlot1ResTime( data ) when SLOT1_ENV_VER setSlot1EnvVer( data ) when SLOT1_ENV_DATE setSlot1EnvDate( data ) when SLOT1_ENV_TIME setSlot1EnvTime( data ) when SLOT1_KERNEL_VER setSlot1KernelVer( data ) when SLOT1_KERNEL_DATE setSlot1KernelDate( data ) when SLOT1_KERNEL_TIME setSlot1KernelTime( data ) when SLOT1_VFAT_VER setSlot1VfatVer( data ) when SLOT1_VFAT_DATE setSlot1VfatDate( data ) when SLOT1_VFAT_TIME setSlot1VfatTime( data ) when SLOT1_ROOTFS_VER setSlot1RootfsVer( data ) when SLOT1_ROOTFS_DATE setSlot1RootfsDate( data ) when SLOT1_ROOTFS_TIME setSlot1RootfsTime( data ) when SLOT1_APP_VER setSlot1ApplVer( data ) when SLOT1_APP_DATE setSlot1AppDate( data ) when SLOT1_APP_TIME setSlot1AppTime( data ) when SLOT1_M0_VER setSlot1M0lVer( data ) when SLOT1_M0_DATE setSlot1M0Date( data ) when SLOT1_M0_TIME setSlot1M0Time( data ) when SLOT2_SUCCESS setSlot2Success( data ) when SLOT2_FAIL_CNT setSlot2FailCnt( data ) when SLOT2_FACT_VER setSlot2FactVer( data ) when SLOT2_FACT_DATE setSlot2FactDate( data ) when SLOT2_FACT_TIME setSlot2FactTime( data ) when SLOT2_BOOT0_VER setSlot2Boot0Ver( data ) when SLOT2_BOOT0_DATE setSlot2Boot0Date( data ) when SLOT2_BOOT0_TIME setSlot2Boot0Time( data ) when SLOT2_UBOOT_VER setSlot2UbootVer( data ) when SLOT2_UBOOT_DATE setSlot2UbootDate( data ) when SLOT2_UBOOT_TIME setSlot2UbootTime( data ) when SLOT2_MBR_VER setSlot2MbrVer( data ) when SLOT2_MBR_DATE setSlot2MbrDate( data ) when SLOT2_MBR_TIME setSlot2MbrTime( data ) when SLOT2_RES_VER setSlot2ResVer( data ) when SLOT2_RES_DATE setSlot2ResDate( data ) when SLOT2_RES_TIME setSlot2ResTime( data ) when SLOT2_ENV_VER setSlot2EnvVer( data ) when SLOT2_ENV_DATE setSlot2EnvDate( data ) when SLOT2_ENV_TIME setSlot2EnvTime( data ) when SLOT2_KERNEL_VER setSlot2KernelVer( data ) when SLOT2_KERNEL_DATE setSlot2KernelDate( data ) when SLOT2_KERNEL_TIME setSlot2KernelTime( data ) when SLOT2_VFAT_VER setSlot2VfatVer( data ) when SLOT2_VFAT_DATE setSlot2VfatDate( data ) when SLOT2_VFAT_TIME setSlot2VfatTime( data ) when SLOT2_ROOTFS_VER setSlot2RootfsVer( data ) when SLOT2_ROOTFS_DATE setSlot2RootfsDate( data ) when SLOT2_ROOTFS_TIME setSlot2RootfsTime( data ) when SLOT2_APP_VER setSlot2ApplVer( data ) when SLOT2_APP_DATE setSlot2AppDate( data ) when SLOT2_APP_TIME setSlot2AppTime( data ) when SLOT2_M0_VER setSlot2M0lVer( data ) when SLOT2_M0_DATE setSlot2M0Date( data ) when SLOT2_M0_TIME setSlot2M0Time( data ) end end end end if __FILE__ == $0 Log4Ienso.log.P_INFO("Starting SysInfo test") MAGIC_CODE = 0 HEADER_VER = 1 ACTIV_SLOT = 2 UUID = 3 MANUFACTER_NAME = 4 PRODUCT_NAME = 5 MODEL_NAME = 6 HARDWARE_ID = 7 SERIOAL_NO = 8 ALIAS_NAME = 9 SLOT1_SUCCESS = 10 SLOT1_FAIL_CNT = 11 SLOT1_FACT_VER = 12 SLOT1_FACT_DATE = 13 SLOT1_FACT_TIME = 14 SLOT1_BOOT0_VER = 15 SLOT1_BOOT0_DATE = 16 SLOT1_BOOT0_TIME = 17 SLOT1_UBOOT_VER = 18 SLOT1_UBOOT_DATE = 19 SLOT1_UBOOT_TIME = 20 SLOT1_MBR_VER = 21 SLOT1_MBR_DATE = 22 SLOT1_MBR_TIME = 23 SLOT1_RES_VER = 24 SLOT1_RES_DATE = 25 SLOT1_RES_TIME = 26 SLOT1_ENV_VER = 27 SLOT1_ENV_DATE = 28 SLOT1_ENV_TIME = 29 SLOT1_KERNEL_VER = 30 SLOT1_KERNEL_DATE = 31 SLOT1_KERNEL_TIME = 32 SLOT1_VFAT_VER = 33 SLOT1_VFAT_DATE = 34 SLOT1_VFAT_TIME = 35 SLOT1_ROOTFS_VER = 36 SLOT1_ROOTFS_DATE = 37 SLOT1_ROOTFS_TIME = 38 SLOT1_APP_VER = 39 SLOT1_APP_DATE = 40 SLOT1_APP_TIME = 41 SLOT1_M0_VER = 42 SLOT1_M0_DATE = 43 SLOT1_M0_TIME = 44 SLOT2_SUCCESS = 45 SLOT2_FAIL_CNT = 46 SLOT2_FACT_VER = 47 SLOT2_FACT_DATE = 48 SLOT2_FACT_TIME = 49 SLOT2_BOOT0_VER = 50 SLOT2_BOOT0_DATE = 51 SLOT2_BOOT0_TIME = 52 SLOT2_UBOOT_VER = 53 SLOT2_UBOOT_DATE = 54 SLOT2_UBOOT_TIME = 55 SLOT2_MBR_VER = 56 SLOT2_MBR_DATE = 57 SLOT2_MBR_TIME = 58 SLOT2_RES_VER = 59 SLOT2_RES_DATE = 60 SLOT2_RES_TIME = 61 SLOT2_ENV_VER = 62 SLOT2_ENV_DATE = 63 SLOT2_ENV_TIME = 64 SLOT2_KERNEL_VER = 65 SLOT2_KERNEL_DATE = 66 SLOT2_KERNEL_TIME = 67 SLOT2_VFAT_VER = 68 SLOT2_VFAT_DATE = 69 SLOT2_VFAT_TIME = 70 SLOT2_ROOTFS_VER = 71 SLOT2_ROOTFS_DATE = 72 SLOT2_ROOTFS_TIME = 73 SLOT2_APP_VER = 74 SLOT2_APP_DATE = 75 SLOT2_APP_TIME = 76 SLOT2_M0_VER = 77 SLOT2_M0_DATE = 78 SLOT2_M0_TIME = 79 a = SysInfo.new() puts(a.getSysInfo(MAGIC_CODE)) puts(a.getSysInfo(HEADER_VER)) puts(a.getSysInfo(ACTIV_SLOT)) puts(a.getSysInfo(UUID)) puts(a.getSysInfo(MANUFACTER_NAME)) puts(a.getSysInfo(PRODUCT_NAME)) puts(a.getSysInfo(MODEL_NAME)) puts(a.getSysInfo(HARDWARE_ID)) puts(a.getSysInfo(SERIOAL_NO)) puts(a.getSysInfo(ALIAS_NAME)) puts(a.getSysInfo(SLOT1_SUCCESS)) puts(a.getSysInfo(SLOT1_FAIL_CNT)) if (a.getHeaderVer == 0x1000000) puts(a.getSysInfo(SLOT1_FACT_VER)) puts(a.getSysInfo(SLOT1_FACT_DATE)) puts(a.getSysInfo(SLOT1_FACT_TIME)) puts(a.getSysInfo(SLOT1_BOOT0_VER)) puts(a.getSysInfo(SLOT1_BOOT0_DATE)) puts(a.getSysInfo(SLOT1_BOOT0_TIME)) end puts(a.getSysInfo(SLOT1_UBOOT_VER)) puts(a.getSysInfo(SLOT1_UBOOT_DATE)) puts(a.getSysInfo(SLOT1_UBOOT_TIME)) if (a.getHeaderVer == 0x1000000) puts(a.getSysInfo(SLOT1_MBR_VER)) puts(a.getSysInfo(SLOT1_MBR_DATE)) puts(a.getSysInfo(SLOT1_MBR_TIME)) puts(a.getSysInfo(SLOT1_RES_VER)) puts(a.getSysInfo(SLOT1_RES_DATE)) puts(a.getSysInfo(SLOT1_RES_TIME)) puts(a.getSysInfo(SLOT1_ENV_VER)) puts(a.getSysInfo(SLOT1_ENV_DATE)) puts(a.getSysInfo(SLOT1_ENV_TIME)) end puts(a.getSysInfo(SLOT1_KERNEL_VER)) puts(a.getSysInfo(SLOT1_KERNEL_DATE)) puts(a.getSysInfo(SLOT1_KERNEL_TIME)) if (a.getHeaderVer == 0x1000000) puts(a.getSysInfo(SLOT1_VFAT_VER)) puts(a.getSysInfo(SLOT1_VFAT_DATE)) puts(a.getSysInfo(SLOT1_VFAT_TIME)) puts(a.getSysInfo(SLOT1_ROOTFS_VER)) puts(a.getSysInfo(SLOT1_ROOTFS_DATE)) puts(a.getSysInfo(SLOT1_ROOTFS_TIME)) end puts(a.getSysInfo(SLOT1_APP_VER)) puts(a.getSysInfo(SLOT1_APP_DATE)) puts(a.getSysInfo(SLOT1_APP_TIME)) puts(a.getSysInfo(SLOT1_M0_VER)) puts(a.getSysInfo(SLOT1_M0_DATE)) puts(a.getSysInfo(SLOT1_M0_TIME)) puts(a.getSysInfo(SLOT2_SUCCESS)) puts(a.getSysInfo(SLOT2_FAIL_CNT)) if (a.getHeaderVer == 0x1000000) puts(a.getSysInfo(SLOT2_FACT_VER)) puts(a.getSysInfo(SLOT2_FACT_DATE)) puts(a.getSysInfo(SLOT2_FACT_TIME)) puts(a.getSysInfo(SLOT2_BOOT0_VER)) puts(a.getSysInfo(SLOT2_BOOT0_DATE)) puts(a.getSysInfo(SLOT2_BOOT0_TIME)) end puts(a.getSysInfo(SLOT2_UBOOT_VER)) puts(a.getSysInfo(SLOT2_UBOOT_DATE)) puts(a.getSysInfo(SLOT2_UBOOT_TIME)) if (a.getHeaderVer == 0x1000000) puts(a.getSysInfo(SLOT2_MBR_VER)) puts(a.getSysInfo(SLOT2_MBR_DATE)) puts(a.getSysInfo(SLOT2_MBR_TIME)) puts(a.getSysInfo(SLOT2_RES_VER)) puts(a.getSysInfo(SLOT2_RES_DATE)) puts(a.getSysInfo(SLOT2_RES_TIME)) puts(a.getSysInfo(SLOT2_ENV_VER)) puts(a.getSysInfo(SLOT2_ENV_DATE)) puts(a.getSysInfo(SLOT2_ENV_TIME)) end puts(a.getSysInfo(SLOT2_KERNEL_VER)) puts(a.getSysInfo(SLOT2_KERNEL_DATE)) puts(a.getSysInfo(SLOT2_KERNEL_TIME)) if (a.getHeaderVer == 0x1000000) puts(a.getSysInfo(SLOT2_VFAT_VER)) puts(a.getSysInfo(SLOT2_VFAT_DATE)) puts(a.getSysInfo(SLOT2_VFAT_TIME)) puts(a.getSysInfo(SLOT2_ROOTFS_VER)) puts(a.getSysInfo(SLOT2_ROOTFS_DATE)) puts(a.getSysInfo(SLOT2_ROOTFS_TIME)) end puts(a.getSysInfo(SLOT2_APP_VER)) puts(a.getSysInfo(SLOT2_APP_DATE)) puts(a.getSysInfo(SLOT2_APP_TIME)) puts(a.getSysInfo(SLOT2_M0_VER)) puts(a.getSysInfo(SLOT2_M0_DATE)) puts(a.getSysInfo(SLOT2_M0_TIME)) endopt/wtc2.0/src/slip.rb0000644000175200017520000000255613557057144015221 0ustar bushnellbushnell END_BYTE = 0300 # indicates end of packet ESC_BYTE = 0333 # indicates byte stuffing ESC_END_BYTE = 0334 # ESC ESC_END means END data byte ESC_ESC_BYTE = 0335 # ESC ESC_ESC means ESC data byte def send_char(char) raise("The user of this library must implement this method") end def recv_char raise("The user of this library must implement this method") end def send_packet(packet) send_char(END_BYTE) # for each byte in the packet, send the appropriate character sequence packet.bytes.each {|byte| case byte when END_BYTE send_char(ESC_BYTE) send_char(ESC_END_BYTE) when ESC_BYTE send_char(ESC_BYTE) send_char(ESC_ESC_BYTE) else send_char(byte) end } send_char(END_BYTE) end def recv_packet packet_data = [] loop { c = recv_char(); case c when END_BYTE if(packet_data.size > 0) return packet_data else next end when ESC_BYTE c = recv_char(); case c when ESC_END_BYTE c = END_BYTE #next when ESC_ESC_BYTE c = ESC_BYTE #next end end packet_data << c } end opt/wtc2.0/src/sleep.sh0000755000175200017520000000236713557057144015374 0ustar bushnellbushnell#!/bin/sh #GPIO=/sys/class/gpio/gpio116/ #if [ ! -d $GPIO ] #then # echo 116 > /sys/class/gpio/export #fi #echo "1" > /sys/class/gpio/gpio116/value #sleep 0.1 #set slow clock #if [ -e /dev/ttyUSB3 ] #then # echo AT+QCFG=\"urc/ri/ring\",\"off\" > /dev/ttyUSB3 # echo AT+QCFG=\"urc/ri/other\",\"off\" > /dev/ttyUSB3 # echo AT+QCFG=\"urc/ri/smsincoming\",\"pulse\",150,3 > /dev/ttyUSB3 # echo at+qcfg=\"risignaltype\",\"physical\" > /dev/ttyUSB3 # sleep 0.3 # echo at+qsclk=1 > /dev/ttyUSB3 # sleep 0.3 # echo at+qgpsend > /dev/ttyUSB3 # #fi #sleep 0.3 # #echo "out" > /sys/class/gpio/gpio116/direction #echo "0" > /sys/class/gpio/gpio116/value #sleep 0.1 #if the suspend fails switch off from here USB=/sys/bus/usb/devices/1-1/authorized if [ -e $USB ] then echo "0" > $USB fi sleep 0.1 rmmod ppp_deflate rmmod bsd_comp rmmod ppp_async rmmod ppp_generic rmmod slhc rmmod option echo $? > result if [ $result==1 ] then echo "killing linked process" ps axf | grep ppp | grep -v grep | awk '{print "kill -9 " $1}' rmmod option fi rmmod usb_wwan echo $? > result if [ $result==1 ] then echo "killing linked process" ps axf | grep ppp | grep -v grep | awk '{print "kill -9 " $1}' rmmod usb_wwan fi rmmod 8723bs opt/wtc2.0/src/camera.rb0000644000175200017520000005046513557057144015504 0ustar bushnellbushnellrequire 'syslog/logger' require 'yaml' require 'dem' require 'optparse' require 'utils' require 'gpio' require 'fileutils' require 'env' require 'thread' require 'debug' APP_NAME = "bushnell-cam-capture" # Camera Control Class # this class is to communication between capture application and ruby class CameraControl include EventSource CMD_SLEEP = 'S' CMD_WAKEUP = 'W' CMD_REQ_RESUME_PIC = 'B' CMD_GET_RESUME_PIC = 'C' CMD_TAKE_PIC = 'D' CMD_REQ_PIC_CONFIG = 'E' CMD_REQ_FLASH = 'F' CMD_REQ_PIC_CONTROL = 'G' CMD_GET_PIC_CONTROL = 'H' CMD_REQ_CAPTURE_MODE = 'I' CMD_GET_PIC_INFO = 'J' CMD_REQ_CIPHER = 'K' CMD_LIGHT_LVL_CHANGE = 'L' CMD_REQ_UPGRADE = 'U' CMD_REQ_SYSINFO = 'M' CMD_REQ_CAM_NAME = 'N' CMD_START_STREAMING = 'V' CMD_STOP_STREAMING = 'X' CMD_DEBUG_REQ_DEBUG = 'Z' CMD_VIDEO_RECODING = 'R' CMD_REQ_LOGGING = 'O' CMD_POWER_OFF = 'P' CMD_ADJUST_EXPOSURE = 'A' ResultFilename = "/tmp/" MaxCmdID = 10 #streaming modes based on use CELL_PHONE_USE = 0 # uncropped, small resolution LENS_FOCUS_UTILITY = 1 # high resolution, cropped # * *Args* : # - config -> configuration value for this class # - env -> setted environment value for the camera def initialize(config, env) @config = config @log = Syslog::Logger.new(@config.log_name) @itemp=-8 Log4Ienso.log.P_INFO("Staring camera") @read_fifo = nil kill_process(APP_NAME) @cap_pid = execute_process(@config.cap_application.path, APP_NAME) @camera_mode = nil # Initialize IR cut filter. Default direction is in config file. @env = env @id = 0 @mutex = Mutex.new @wating_cmd = 0 if(@config.ir_leds.gpios.enable_negagive != nil) pinNum = @config.ir_leds.gpios.enable_negagive else pinNum = nil end @ir_negative = Gpio.new(pinNum) @ir_negative.direction = 'out' @ir_negative.clear init_ir_cut_filter sleep 3 #for sync set_image_vid_resolution(@env.get_env_value('capture_mode')) if(@camera_mode == 'day') set_shutter_speed('high') else set_shutter_speed(@env.get_env_value('shutter_speed')) end set_image_banner(@env.get_env_value('show_timestamp')) adjust_exposure(30) ObjectSpace.define_finalizer(self, self.class.method(:finalize).to_proc) end def set_image_vid_resolution(val) if(val == 'image') set_resolution(@env.get_env_value('image_resoluition')) else set_resolution_video(@env.get_env('movie_resoluition')) end end def refreshEnv(env) @env = env end # night mode change # * *Args* : # - level -> IR LED level def set_night(level = nil) if $model=="impulse" if(@camera_mode != 'night') Log4Ienso.log.P_INFO("set camera mode to night mode") @camera_mode = 'night' if(level == nil) level = @env.get_env_value('led_power') end #level = 'med' #temporary set_ir_led_power(level) set_shutter_speed(@env.get_env_value('shutter_speed')) end @ir_cut_direction_positive.clear @ir_cut_direction_negative.set ir_cut_pulse_power @ir_cut_direction_positive.clear @ir_cut_direction_negative.clear @ir_negative.clear end if $model == "primos" if(@camera_mode != 'night') Log4Ienso.log.P_INFO("set camera mode to night mode") @camera_mode = 'night' if(level == nil) level = @env.get_env_value('led_power') end #level = 'med' #temporary set_ir_led_power(level) set_shutter_speed(@env.get_env_value('shutter_speed')) end @ir_cut_direction_positive.set @ir_cut_direction_negative.clear ir_cut_pulse_power #@ir_cut_direction_positive.clear #@ir_cut_direction_negative.clear #@ir_negative.clear end end def set_night2(level = nil) Log4Ienso.log.P_INFO("set camera mode to night mode 2") @ir_cut_direction_positive.clear @ir_cut_direction_negative.set ir_cut_pulse_power @ir_cut_direction_positive.clear @ir_cut_direction_negative.clear @ir_negative.clear end def set_day2() Log4Ienso.log.P_INFO("set camera mode to day mode 2") @ir_cut_direction_positive.set @ir_cut_direction_negative.clear ir_cut_pulse_power @ir_cut_direction_positive.clear @ir_cut_direction_negative.clear @ir_negative.set end # day mode change def set_day() if $model == "impulse" if(@camera_mode != 'day') Log4Ienso.log.P_INFO("set camera mode to day mode") @camera_mode = 'day' set_ir_led_power() set_shutter_speed('high') end @ir_cut_direction_positive.set @ir_cut_direction_negative.clear ir_cut_pulse_power @ir_cut_direction_positive.clear @ir_cut_direction_negative.clear @ir_negative.set end if $model == "primos" if(@camera_mode != 'day') Log4Ienso.log.P_INFO("set camera mode to day mode") @camera_mode = 'day' set_ir_led_power() set_shutter_speed('high') end @ir_cut_direction_positive.clear @ir_cut_direction_negative.set ir_cut_pulse_power #@ir_cut_direction_positive.clear #@ir_cut_direction_negative.clear #@ir_negative.set end end # * *Returns* : # - Day('D') or Night('N') def get_day_night_state Log4Ienso.log.P_INFO("get day night state camera_mode=#{@camera_mode}") day = 'D' if(@camera_mode == 'night') day = 'N' end day end # take a picture # * *Args* : # - num -> number of picture # * *Returns* : # - captured image name prefix def capture_image(num, filter = nil) Log4Ienso.log.P_INFO("capture_image filter=#{filter}") if(filter != nil) current_ir = @camera_mode if(filter == :night) set_night else set_day end end ret = send_cmd(CMD_TAKE_PIC,0 ,num) adjust_exposure_after_capture() if(current_ir != nil) ir_cut_change(current_ir) end ret[:id] end def capture_video(num) #config={}) #ret = send_cmd(CMD_VIDEO_RECODING, num) ret = send_cmd(CMD_TAKE_PIC, 1, num) ret[:id] end # it is to Notify to capture-application that the system will be going to suspend mode # and request to take pictures when the system resume, # * *Args* : # - num -> number of picture def req_resume_take_pic(num) if(num == nil) num = 1 end send_cmd(CMD_REQ_RESUME_PIC,0 , num)[:id] end def req_resume_take_vid(num) if(num == nil) num = 1 end send_cmd(CMD_REQ_RESUME_PIC,1 , num)[:id] end # when the system resume, it is to get the picture # and request to take pictures when the system resume, # * *Args* : # - num -> number of picture def get_resume_take_pic(num) if(num == nil) num = 1 end ret = send_cmd(CMD_GET_RESUME_PIC,0 , num)[:id] adjust_exposure_after_capture() ret end # getting the camera gain # * *Returns* : # - gain def get_gain() send_cmd(CMD_GET_PIC_INFO, 0)[:val].to_f/1000 end # getting the exposure time # * *Returns* : # - exposure time def get_exposure() send_cmd(CMD_GET_PIC_INFO, 1)[:val].to_f/1000 end def get_brightness() send_cmd(CMD_GET_PIC_INFO, 2)[:val].to_i end # It will be called when the application was killed and it will kill the capture-application def CameraControl.finalize(id) pids = `pidof #{APP_NAME}` pida = pids.split(' ') pida.each{|pid| Process.kill "USR2", pid.to_i } end def set_sleep() send_cmd(CMD_SLEEP, 0)[:id] end def set_wakeup() send_cmd(CMD_WAKEUP, 0)[:id] end def light_lvl_change() Log4Ienso.log.P_INFO("========= camera light level change =====") #send_cmd(CMD_LIGHT_LVL_CHANGE, 0)[:id] adjust_exposure(20) end def start_streaming(mode) Log4Ienso.log.P_NOTICE("Starting streaming") if mode == CELL_PHONE_USE width = 960 height =540 crop = 0 #full image elsif mode == LENS_FOCUS_UTILITY width =1280 height = 720 crop = 1 #cropped end send_cmd(CMD_START_STREAMING, width, height , crop)[:id] end def stop_streaming Log4Ienso.log.P_NOTICE("End streaming") send_cmd(CMD_STOP_STREAMING, 0)[:id] end def request_upgrade(path = nil,key =nil, cnt=0) Log4Ienso.log.P_INFO("request upgrade path=#{path} key=#{key} count=#{cnt}") send_cmd(CMD_REQ_UPGRADE, path, key, cnt)[:val] end def request_encrypt(input_path = nil,output_path =nil) Log4Ienso.log.P_INFO("request encryption file input file=#{input_path} output file=#{output_path}") send_cmd(CMD_REQ_CIPHER, input_path, output_path )[:val] end def request_logging(enable = 1,path =nil) Log4Ienso.log.P_INFO("request logging file enable=#{enable} input file=#{path} ") send_cmd(CMD_REQ_LOGGING, enable, path )[:val] end def power_off() Log4Ienso.log.P_INFO("request power off") send_cmd(CMD_POWER_OFF, 0)[:id] end def set_hybrid(val) end def set_resolution_video(val) if val == '720p30' width = 1280 height = 720 elsif val == '1080p30' width = 1920 height = 1080 elsif val == '640x480' width = 640 height = 480 else width = 960 height = 540 end Log4Ienso.log.P_INFO("set resolution video [#{val}] [#{width}x#{height}]") send_cmd(CMD_REQ_PIC_CONFIG, 0, width, height)[:id] end def set_resolution(val = '8') if $model == 'primos' if val == '3' width = 2000 height = 1000 elsif val == '16' width = 4620 height = 3460 else #8 width = 3264 height = 2448 end end if $model == 'impulse' if(@env.get_env_value('pic_format') == '3to2') if val == '2' width = 1744 height = 1152 elsif val == '5' width = 2752 height = 1824 elsif val == '20' width = 5504 height = 3648 else width = 3488 height = 2304 end else if val == '2' width = 1920 height = 1080 elsif val == '5' width = 2982 height = 1678 elsif val == '20' width = 5964 height = 3354 else width = 3780 height = 2128 end end end Log4Ienso.log.P_INFO("pic_format #{@env.get_env_value('pic_format')} set resolution [#{val}] [#{width}x#{height}]") send_cmd(CMD_REQ_PIC_CONFIG, 0, width, height)[:id] end def set_frame_rate( ) frame_rate = 20 Log4Ienso.log.P_CLEAN("set_frame_rate. Mode = #{@camera_mode}.") cap_mode = @env.get_env_value('capture_mode') if( (@camera_mode == 'night') && (cap_mode == 'image') ) val = @env.get_env_value('shutter_speed') if val == 'low' frame_rate = 10 elsif val == 'med' frame_rate = 15 else frame_rate = 20 end end if( (@camera_mode == 'day') && (cap_mode == 'image') ) frame_rate = 23 end Log4Ienso.log.P_INFO("set_frame_rate [#{frame_rate}] ") send_cmd(CMD_REQ_PIC_CONFIG, 3, frame_rate)[:id] adjust_exposure(3) end # changing shutter speed # * *Args* : # - val -> high, med, low speed def set_shutter_speed(val = 'low', override = false) param = 1 #if(@camera_mode == 'day') if val == 'high' param = 3 elsif val == 'med' param = 2 elsif val == 'low' param = 1 else @log.error("shutter_speed error [#{val}}") end #end Log4Ienso.log.P_INFO("set_shutter_speed [#{val}]") Log4Ienso.log.P_INFO("set_shutter_speed [#{val}] [#{param}]") send_cmd(CMD_REQ_PIC_CONFIG, 5, param)[:id] adjust_exposure(3) set_frame_rate( ) end def set_temp(temp = 0) #if @itemp > -12 # @itemp -= 1 #else # @itemp = -8 #end #temp=@itemp Log4Ienso.log.P_INFO("set_camera_temp [#{temp}]") Log4Ienso.log.P_INFO("set_camera_temp [#{temp}] ") send_cmd(CMD_REQ_PIC_CONFIG, 6, temp)[:id] end def set_image_banner(val = 'on') param = 1 if val == 'off' param = 0 end Log4Ienso.log.P_INFO("set_image_banner[#{val}]") Log4Ienso.log.P_INFO("set_image_banner [#{val}] [#{param}]") send_cmd(CMD_REQ_PIC_CONFIG, 7, param)[:id] end def set_pir_mode(mode = 0) Log4Ienso.log.P_INFO("set_pir_mode[#{mode}]") Log4Ienso.log.P_INFO("set_pir_mode [#{mode}]") send_cmd(CMD_REQ_PIC_CONFIG, 8, mode)[:id] end def set_capture_type(type = 0) Log4Ienso.log.P_INFO("set_capture_type [#{type}]") if(type == 'image') send_cmd(CMD_REQ_PIC_CONFIG, 9, 0)[:id] else send_cmd(CMD_REQ_PIC_CONFIG, 9, 1)[:id] end end def set_camera_name(name = ' ') name2=name.ljust(13) Log4Ienso.log.P_INFO("set_camera_name[#{name2}]") Log4Ienso.log.P_INFO("set_camera_name [#{name2}]") send_cmd(CMD_REQ_CAM_NAME, name2)[:id] end # changing ir led power # * *Args* : # - val -> high, med, low speed def set_ir_led_power(level = nil) lev = 0 if(level != nil) if(level == 'high') lev = 3 elsif(level == 'med') lev = 2 elsif(level == 'low') lev = 1 else lev = 0 end end send_cmd(CMD_REQ_FLASH,lev) adjust_exposure(3) end def get_sysinfo(n_id = 0, n_slot = 0, n_module = 0) ret = send_cmd( CMD_REQ_SYSINFO, n_id, n_slot, n_module ) if (ret[:val] == '0') Log4Ienso.log.P_INFO("????????????? firmware version = #{ret[:val2]}") else Log4Ienso.log.P_INFO("Warning:.............. firmware version = reading error =#{ret[:val]}") ret [:val2] = nil end ret [:val2] end def get_active_slot(n_id = SYSINFO_ACTIVE_SLOT, n_slot = 0, n_module = 0) ret = send_cmd( CMD_REQ_SYSINFO, n_id, n_slot, n_module ) if (ret[:val] == '0') Log4Ienso.log.P_INFO("????????????? active slot = #{ret[:val2]}") else Log4Ienso.log.P_INFO("Warning:.............. active slot = reading error =#{ret[:val]}") ret [:val2] = nil end ret [:val2] end def adjust_exposure(frame_number = 10) Log4Ienso.log.P_INFO("========= camera expusure adjusted for #{frame_number} times=====") send_cmd(CMD_ADJUST_EXPOSURE, frame_number)[:id] end def adjust_exposure_after_capture() delay = @env.get_env_value('imaage_interval') if delay == 1 adjust_exposure(4) else adjust_exposure() end end private def execute_process(path,name) if File.exists?(@config.cap_application.rxfifo) FileUtils.rm(@config.cap_application.rxfifo) end if File.exists?(@config.cap_application.txfifo) FileUtils.rm(@config.cap_application.txfifo) end File.mkfifo(@config.cap_application.rxfifo) system("#{path}#{name} #{@config.cap_application.txfifo} #{@config.cap_application.rxfifo} &") @read_fifo = File.open(@config.cap_application.rxfifo, "r") `pidof #{name}` end def kill_process(name) pids = `pidof #{name}` pida = pids.split(' ') pida.each{|pid| Log4Ienso.log.P_WARN("kill #{name}") Process.kill "USR2", pid.to_i sleep(1) } @read_fifo = nil end def check_process(name) pids = `pidof #{name}` pida = pids.split(' ') pida.count > 0 end def ir_cut_pulse_power @ir_cut_power_gpio.set sleep(@config.ir_filter.pulse_width) @ir_cut_power_gpio.clear end def send_cmd(cmd, p1, p2 = nil, p3 = nil, p4 = nil, p5 = nil) id = nil val = val2 = nil @mutex.synchronize{ id = @id = (@id+1)%MaxCmdID cmd = "#{id},#{cmd},#{p1}" cmd += ",#{p2}" if p2 != nil cmd += ",#{p3}" if p3 != nil cmd += ",#{p4}" if p4 != nil cmd += ",#{p5}" if p5 != nil cmd += ',*' Log4Ienso.log.P_NOTICE("[Ruby - C] cmd = #{cmd}") if File.exists?(@config.cap_application.txfifo) File.open(@config.cap_application.txfifo, 'w'){|f| f.write(cmd) } val, val2 = check_cmd_result(id) else @log.error("capture_image: capture application doesn't start") id = nil end } ret = {:id => id, :val => val, :val2 => val2} end def check_cmd_result(id = nil) begin in_val = @read_fifo.gets.split(',') if id == in_val[0].to_i val = in_val[1] if( in_val[2] != nil) val2 = in_val[2] else val2 = nil end else @log.error("image capture application communication error") Log4Ienso.log.P_ERR("image capture application communication error. expect id=#{id}, rcv id=#{in_val[0]} ret=#{val}") end rescue Exception => e Log4Ienso.log.P_ERR("Exception: #{e} id=#{id}") Log4Ienso.log.P_ERR(e.backtrace) val = 0 end return val, val2 end def init_ir_cut_filter Log4Ienso.log.P_NOTICE("IR CUT INIT +++++++++++++++++") pinNum = nil if(@config.ir_filter.gpios.power != nil) pinNum = @config.ir_filter.gpios.power; end @ir_cut_power_gpio = Gpio.new(pinNum) if(@config.ir_filter.gpios.direction_positive != nil) pinNum = @config.ir_filter.gpios.direction_positive; else pinNum = nil end @ir_cut_direction_positive = Gpio.new(pinNum) if(@config.ir_filter.gpios.direction_negative != nil) pinNum = @config.ir_filter.gpios.direction_negative; else pinNum = nil end @ir_cut_direction_negative = Gpio.new(pinNum) @ir_cut_power_gpio.direction='out' @ir_cut_direction_positive.direction='out' @ir_cut_direction_negative.direction='out' end def ir_cut_change( state ) if(state == :day) set_day Log4Ienso.log.P_NOTICE("SET DAY +++++++++++++++++") elsif(state == :night) set_night Log4Ienso.log.P_NOTICE("SET NIGHT +++++++++++++++++") end end def ir_cut_togle if(@camera_mode == 'night') set_day Log4Ienso.log.P_NOTICE("SET DAY +++++++++++++++++") else set_night Log4Ienso.log.P_NOTICE("SET NIGHT +++++++++++++++++") end end end if $0 == __FILE__ path = "/tmp/bushnell-trailcam-fifo" if File.exists?(path) File.open(path, 'w'){|f| f.write("D1") } end end opt/wtc2.0/src/constants.rb0000644000175200017520000000676413557057144016273 0ustar bushnellbushnellclass Constant SLEEP_GUARD_TIME = 3 PICTURE_BURST_TIME = 1 MAX_SERVER_SNED_QUE = 1 MAX_CAP_QUE = 10 MAX_NETWORK_TRY_COUNT = 2 # max no of times, network will be checked on resume #possible states of the modem MODEM_REBOOT = 0 # modem will not work wihout a reboot of quectel modem, should sleep MODEM_OFF = 1 # covers suspended and low power mode sleep and fails, can sleep MODEM_CONNECTING = 2 # in the process of switching on and dialing ppp, cannot sleep MODEM_PORTS_AVAILABLE = 3 # can talk to A83, but no network as yet MODEM_CONNECTED = 4 # got ip and wating for job, cannot sleep MODEM_STARTING_UPLOAD = 5 # starting upload or in the midst of it, cannot sleep MODEM_FINISHED_UPLOAD = 6 # complted upload , cannot sleep until no more uploads / downloads MODEM_IDLE = 7 # all work done can go to sleep:103 #GPS STATES GPS_ABORTED = 0 GPS_SWITCHED_OFF = 1 GPS_STARTED = 2 GPS_FINDING_FIX = 3 GPS_FIXED = 4 #CONNECTION STATES UPLOAD_PHOTOS_AND_SERVER_CMDS = 0 # the sendPhotos thread on pir, fieldscan triggers will be in this mode GET_SERVER_CMDS_ONLY = 1 # on sms and A83 wakeup this will be default mode #PICTURE SENDING MODES SEND_PIC_NOW = 0 #default mode SEND_PIC_DAILY = 1 #only on 24 check in SEND_PIC_NEVER = 2 #never upload pictures #Abort timings in seconds NO_GPS_DATA_TIME = 120 GPS_DATA_TIME = 60 GPS_WAIT_TIME = 60 GPS_CHECK_TIME = 2 THEFT_MODE_TIME = 90 OTA_UPDATE_TIME = 300 #90 seconds on LTE is good, but 3G requires longer time WIFI_TIME = $wifi_timeout SEND_PHOTO_DELAY = 1.0 SEND_VIDEO_DELAY = 2.5 FAILED_DAILY_ALERT_RETRYTIME = 7200 #2hrs PHOTO_UPLOAD_ABORT_TIME = 70 #seconds GPS_CHECK_DELAY = 5 #seconds FFMPEG_ENCODING_TIME = 10 #seconds #not encoding any more therefore reduced time LONG_VIDEO_TIME = 90 #daily checkin states FIRST_ATTEMPT_ON_TRIGGER = 0 FAILED_ONCE = 1 FAILED_TWICE = 2 #sd card read for photos READ_SD_CARD = 0 DONOT_READ_SD_CARD = 1 #OTA firmware mode UPGRADE_OR_DOWNGRADE_FIRMWARE = 0 ONLY_UPGRADE_FIRMWARE = 1 #sysinfo code for camera model name MODEL_NAME = 6 #LOG_FILE = '/var/wtc2.0/messages_verbose.txt' LOG_FILE = '/var/log/messages_verbose.txt' LOG_FILE_PREVIOUS = '/var/log/messages_verbose.txt.1' MAX_VERBOSE_LOG_FILE = 5242880 #5MB before it gets truncated #GPS try count GPS_TRY_COUNT = 3 FINAL_TEST_FILE_NAME = "t##@@@.txt" TEST_SERVER_FILE = "imei.txt" UPLOAD_BATCH_SIZE = 60 #No of photos that can load in one wakeup MAX_PARALLEL_UPLOAD_LIMIT = 8 # no of thumbnails that be uploaded in parallel. Based on 2.5 MBits/sec COLD_BOOT = 0 RESUME_WAKEUP = 1 STREAMING_OFF = 0 STREAMING_ON = 1 INTERFACE_PPP = 0 INTERFACE_WWAN = 1 OPERATOR_LIST = 0 CURRENT_OPERATOR = 1 NETWORK_REGN_STATE =2 OPERATOR_NAMES=3 NETWORK_TYPE=4 FAKE_PIR_WAIT_TIME=0.2 NETWORKS={'14800'=>'VERIZON','30272'=>'ROGERS_US','30269'=>'BELL','01170'=>'ATT','31085'=>'KPN'} HIRES_PATH = "/media/photos/DCIM/" RESULT_CODES = [ "OK", "CONNECT", "RING", "NO_CARRIER", "ERROR", "NO_DIALTONE", "BUSY", "NO_ANSWER" ] end opt/wtc2.0/src/connection_manager.rb0000644000175200017520000021567113557057144020107 0ustar bushnellbushnellrequire 'timeout' require 'yaml' require 'optparse' require 'syslog/logger' require 'mqtt_rpc' require 'utils' require 'gpio' require 'lte.rb' require 'quectel.rb' require 'http_rest_zipit.rb' require 'syslog/logger' require 'debug' require 'json' require 'constants' # Lte modem setup and ppp connection management class ConnectionManager include EventSource include EventListener def initialize(config) @config = config @log = Syslog::Logger.new(@config.control.log_name) @manifest = nil @trackingstate="0" # 1 is on @trackingstatus = 0 init() end def init() @modem = nil @imsi=@imei=@iccid=@apiendpoint=@sessiontokenfile=nil @readytosleep=0 @uploadStartTime=0 @zipit = nil @connected=0 @accesscontrol = Mutex.new @timecontrol = Mutex.new @threadcount=0 @modemconnected = 0 @modemportsavailable = 0 @globalfail = 0 @zipitStatusCode = "N/A" @storageused = 0 @storagesize = 0 @battery = 100 # default to 100%. Prevents web server from sending SMS message to user to say batteries need replacing. # It is necessary to do this here because battery capacity may not be available imediately upon cold boot. @latitude = 0 @longitude = 0 @rssi = 3 # default to 3 , used as value for first Tx, until actual value is available. @gpstime="1970-01-01T12:00:00" @wifistate="0" # 1 is on @cameraStatusUpdated = false @waitForGPS = 0 @isGPSSessionActive = false @isOTASessionActive = false @isNextPhotoAvailable = false @network_state_desc = "Not attempted" @networkstate = 0 @cutoffnotification = false @vidrecstarttime = 0 @sentthissession = false Log4Ienso.log.P_NOTICE("Init connection manager") end def setLocalTime(mode=0) if @quectelcmds == nil @quectelcmds = QuectelATCommands.new(@modem.getCommandPort,@config.control.log_name,@modem.getLteConfigFile) end if @quectelcmds != nil if $final_test_flag ret = @quectelcmds.updateTZ ret = @quectelcmds.enableTZReporting return end ret = @quectelcmds.setLocalTime(mode) if ret == nil or ret == "" Log4Ienso.log.P_ERR("------- Getting Local Time failed ---------") else Log4Ienso.log.P_CLEAN("Local Time Set Properly = #{ret}") $lastupdatetime = Time.now.strftime("%Y-%m-%dT%H:%M:%S") #init the synchronization time with server notify("modem/clock_updated") if mode == 0 #only update time if it needs changing end end end def enableModemOnly(starttype) notify("modem/started") @modem = LteModem.new(@config) if @modem == nil modemval = @modem.enableModem(starttype) # this will create the data ports if( modemval.to_i == 5 ) Log4Ienso.log.P_INFO("Modem @modemval error #{@modemval}") notify("modem/reboot") return else @quectelcmds = QuectelATCommands.new(@modem.getCommandPort,@config.control.log_name,@modem.getLteConfigFile) portcount = `ls -l /dev/ttyUSB* | wc -l` if portcount.chomp.strip.to_i == @config.ltectrl.tty_port_count @modemconnected = 1 count=0 dtcheck=`date +%Y` #get the year dtcheck = dtcheck.chomp.strip while dtcheck == "1970" do if starttype != Constant::COLD_BOOT #the network time sometimes is not available on cold boot #@quectelcmds.setLocalTime() setLocalTime() else Log4Ienso.log.P_WARN("Getting NTP time on cold boot") @modem.setTimeFromNetwork if @modem != nil end sleep(0.3) dtcheck=`date +%Y` #get the year dtcheck = dtcheck.chomp.strip count+=1 if count > 3 Log4Ienso.log.P_WARN("###################### TRIED 3 TIMES AND DID NOT GET CARRIER TIME, now going to NTP server ###############") @modem.setTimeFromNetwork if @modem != nil break end end dtcheck=`date +%Y` dtcheck = dtcheck.chomp.strip if dtcheck != "1970" if $testserver == nil @imei,@iccid = @quectelcmds.getIMEIandICCID(starttype) else @imei = $imei @iccid = $iccid end notify("modem/connected") return end end end notify("modem/reboot") end def getIMEIandICCIDForMenu return @imei,@iccid end def getUpdatedQLTStime(qlts) rawdate = qlts.split("QLTS:") year=month=day=hour=0 len =0 if rawdate[1] != nil rawdate[1].gsub!(/\"|"\Z/, '' ) if( rawdate[1] == nil) return -1,-1,-1,-1 end len = rawdate[1].strip.chomp.length Log4Ienso.log.P_INFO( "the length of qlts is #{ len.to_s} ") end if len > 20 data = rawdate[1].split(",") ymd = data[0].split("/") year = ymd[0] month = ymd[1] day = ymd[2] Log4Ienso.log.P_INFO("QLTS year is #{year} | #{month}| #{day} << ") hrminsec = data[1].split(":") hour = hrminsec[0] return year,month,day,hour end return -1,-1,-1,-1 end def fixOmaSolution1() if isModemAvailable == true && @quectelcmds != nil if ($networkname == "ATT") reply = @quectelcmds.sendATCmdRaw("at+qflst=\"../../usr/fota_ip_a/update_report.ur\"") if (reply.length == 0) Log4Ienso.log.P_INFO("checkOmaSolution1: Auto report feature is ENABLED, should disable it") reply = @quectelcmds.sendATCmdRaw("at+qfopen=\"../../usr/fota_ip_a/update_report.ur\",1") if (reply.include? "+QFOPEN: 4") Log4Ienso.log.P_INFO("checkOmaSolution1: Auto report feature HAS BEEN disabled") notify("modem/reboot") return 1 else Log4Ienso.log.P_ERR("checkOmaSolution1: Auto report feature disable FAILED!!!") end else Log4Ienso.log.P_INFO("checkOmaSolution1: Auto report feature ALREADY disabled") end end end return 0 end def gpsAidingDataValid() # returns -1 to indicate failure # returns 0 - Data expired # returns x - Remaining time in seconds valid_secs = -1 if isModemAvailable == true && @quectelcmds != nil reply = @quectelcmds.sendATCmdRaw("AT+QGPSXTRADATA?") #Response: +QGPSXTRADATA: , # +QGPSXTRADATA: 10080,"2019/07/11,19:00:00" if (reply.include? "+QGPSXTRADATA:") raw = reply.split("+QGPSXTRADATA:") data = raw[1].split(",",2) dur = data[0].chomp inject = data[1].chomp mins = dur.to_i dt_begin = Time.parse(inject) dt_end = dt_begin + mins*60 utc = Time.now.utc #Log4Ienso.log.P_INFO("gpsAidingDataValid: Aiding start: #{dt_begin}") #Log4Ienso.log.P_INFO("gpsAidingDataValid: Time Now: #{utc}") #Log4Ienso.log.P_INFO("gpsAidingDataValid: Aiding end: #{dt_end}") if utc > dt_begin && utc < dt_end valid_secs = dt_end - utc days = valid_secs / (60 * 60 * 24) days = days.to_i secs = valid_secs % (60 * 60 * 24) secs = secs.to_i valid_time = Time.at(secs).utc.strftime("%H:%M:%S") Log4Ienso.log.P_WARN("gpsAidingDataValid: Aiding data VALID for #{days} days #{valid_time}") else valid_secs = 0 Log4Ienso.log.P_WARN("gpsAidingDataValid: Aiding data has EXPIRED") end else Log4Ienso.log.P_ERR("gpsAidingDataValid: Error checking validity") end end return valid_secs end def gpsGetXtraTimeString() # The camera time is set using localtime, but the timezone in linux is not updated # so Time.now.utc will always == Time.now # So to Work around this(Hack) use the global camera_timezone tz = $camera_timezone.to_i if tz == 0 Log4Ienso.log.P_ERR("gpsGetXtraTimeString: TZ may NOT be set") end now = Time.now utc = Time.now.utc utc = utc + (tz * 60 * 60) dtstr = utc.strftime("%Y/%m/%d,%H:%M:%S") Log4Ienso.log.P_NOTICE("gpsGetXtraTimeString: local[#{now}] utc[#{utc}] xtra[#{dtstr}]") return dtstr end def enableGPS() r="FAIL" if isModemAvailable == true && @quectelcmds != nil Log4Ienso.log.P_CLEAN("enableGPS: Starting GPS Session") @quectelcmds.sendATCmdRaw("at+qgpsend") secs = gpsAidingDataValid() if secs > 120 dt = gpsGetXtraTimeString() # set the aiding time Format: YYYY/MM/DD,hh:mm:ss. e.g. 2016/01/03,15:34:50 @quectelcmds.sendATCmdRaw("AT+QGPSXTRATIME=0,\"#{dt}\"") # enabling gps extra @quectelcmds.sendATCmdRaw("at+qgpsxtra=1") end r = @quectelcmds.sendATCmdRaw("at+qgps=1,30,100,0,1") #r = @quectelcmds.sendATCmdRaw("at+qgps=1") r = r.to_s r = r.chomp.strip if r != nil if r.include? "504" Log4Ienso.log.P_NOTICE("enableGPS: GPS Session already started" + r.to_s ) r="504" end r="504" #force else Log4Ienso.log.P_NOTICE("enableGPS: Cannot switch on GPS ... no ports") end return r end def turn_off_radio() count = 0 r=nil if isModemAvailable == true && @quectelcmds != nil while count < 3 do count +=1 if $networkname == 'VERIZON' r = @quectelcmds.sendATCmdRaw('AT+QRFTEST="LTE BAND13", 23210, "OFF",1') else r = @quectelcmds.sendATCmdRaw('AT+QRFTEST="LTE BAND12", 23064, "OFF",1') end next if r == nil Log4Ienso.log.P_NOTICE("radio off cmd return=#{r}") if r.include? "ALL is off" break end next end Log4Ienso.log.P_NOTICE("radio off AT command =at+qrftestmode=0 ") r = @quectelcmds.sendATCmdRaw("at+qrftestmode=0") end r end def turn_on_radio() count = 0 r=nil if isModemAvailable == true && @quectelcmds != nil while count < 3 do count +=1 Log4Ienso.log.P_NOTICE("radio on AT command =at+qrftestmode=1 ") r = @quectelcmds.sendATCmdRaw("at+qrftestmode=1") Log4Ienso.log.P_NOTICE("radio on cmd return=#{r}") if r != nil if $networkname == 'VERIZON' r = @quectelcmds.sendATCmdRaw('AT+QRFTEST="LTE BAND13", 23210, "ON",15') else r = @quectelcmds.sendATCmdRaw('AT+QRFTEST="LTE BAND12", 23064, "ON",15') end next if r == nil Log4Ienso.log.P_NOTICE("radio on set channel cmd return=#{r}") if r.include? "ALL IS UP" break end next end if (count >= 3) Log4Ienso.log.P_ERR("Warning:radio on AT command failed ") end end r end def convert_lat lat, dir if ( lat == nil) return 0 end degrees = lat[0,2].to_f + (lat[2,lat.length-2].to_f / 60.0) degrees = (degrees * -1) if dir == 'S' return degrees end # lon is of the form 01131.000 where the first 3 digits are degrees and # the remainder is minutes. # dir is either 'E', or 'W' def convert_lon lon, dir if ( lon == nil) return 0 end degrees = lon[0,3].to_f + (lon[3,lon.length-2].to_f / 60.0) degrees = (degrees * -1) if dir == 'W' return degrees end def shutdownModem Log4Ienso.log.P_NOTICE("shutdownModem: unloading drivers") #@modem.startSleep sleepModem #Log4Ienso.log.P_NOTICE("calling modem shutdown") #@modem.shutdownModem end def sleepModem Log4Ienso.log.P_NOTICE("sleepModem: ENTER") avgTTFF = 0 if $gpsTTFFcnt > 0 avgTTFF = $gpsTTFFsum / $gpsTTFFcnt avgTTFF = avgTTFF.round(1) end Log4Ienso.log.P_WARN("Aeronix: atERRORs: #{$atERRORs} last: #{$atERRORcmd}") Log4Ienso.log.P_WARN(" tzERRORs: #{$tzERRORs}") Log4Ienso.log.P_WARN(" ftpERRORs: #{$ftpERRORs}") Log4Ienso.log.P_WARN(" gpsFIXes: #{$gpsTTFFcnt}/#{$gpsFixAttemps} @ #{avgTTFF}s") # @modem.startSleep # Moved from @modem.startSleep to here if $model == "impulse" vbus_gpio = Gpio.new('PD20') vbus_gpio.direction = 'out' vbus_gpio.set sleep(0.5) if @quectelcmds != nil #r = @quectelcmds.sendATCmdRaw("AT+QCFG=\"urc/ri/ring\",\"off\"") #r = @quectelcmds.sendATCmdRaw("AT+QCFG=\"urc/ri/other\",\"off\"") #r = @quectelcmds.sendATCmdRaw("AT+QCFG=\"urc/ri/smsincoming\",\"pulse\",150,3") #r = @quectelcmds.sendATCmdRaw("AT+QCFG=\"risignaltype\",\"physical\"") begin if File.exist?('/dev/ttyUSB3') && $model == "impulse" r = @quectelcmds.sendATCmdRaw("at+qsclk=1") r = @quectelcmds.sendATCmdRaw("at+qgpsend") else Log4Ienso.log.P_ERR("sleepModem: /dev/ttyUSB3 NOT AVAILABLE - slow clock not set!") end rescue => e Log4Ienso.log.P_WARN("sleepModem: #{e}") end end vbus_gpio.clear sleep(0.5) Log4Ienso.log.P_NOTICE("sleepModem: sleep.sh CALL") system(%Q(/opt/wtc2.0/src/sleep.sh)) Log4Ienso.log.P_NOTICE("sleepModem: sleep.sh RETURN") end if $model == "primos" system(%Q(/opt/wtc2.0/src/sleep_primos.sh)) if$model == "primos" end Log4Ienso.log.P_NOTICE("sleepModem: EXIT") end def getGPSData() if !File.exist?('/dev/ttyUSB1') Log4Ienso.log.P_NOTICE("GPS diconnected from port /=x ") return 0,0,"FAIL" end Log4Ienso.log.P_NOTICE("Query GPS start...") #+QGPSLOC: 061951.0,3150.7223N,11711.9293E,0.7,62.2,2,0.0,0.0,0.0,110513,09 if @quectelcmds != nil # @quectelcmds.sendATCmdRaw("at+qgpsgnmea=\"GSV\"") # @quectelcmds.sendATCmdRaw("at+qgpsgnmea=\"GSA\"") r = @quectelcmds.sendATCmdRaw("at+qgpsloc?") r = r.strip.chomp if r != nil if r != nil nmea = r.split(",") if nmea != nil if nmea.length < 3 return 0,0,0,0 end end timea = nmea[0] gtime =timea.split(":") if timea != nil lat = nmea[1].strip.chomp latx = lat[0..lat.length-2] if lat != nil latd = lat[-1..-1] latx = convert_lat(latx,latd) lng = nmea[2].strip.chomp lngx = lng[0..lng.length-2] if lng != 0 lngd = lng[-1..-1] lngx = convert_lon(lngx,lngd) sat = nmea[10] errcode = nmea[11] Log4Ienso.log.P_NOTICE(" lat is " +latx.to_s + "lng is " + lngx.to_s) #return gtime,latx,latd,lngx,lngd return latx,lngx,"FIX" else Log4Ienso.log.P_NOTICE("Query GPS end... return val is null") return 0,0,"FAIL" end end end def getGPSData1 lat_decimal = lng_decimal = 0 nmeadata="" if !File.exist?('/dev/ttyUSB1') Log4Ienso.log.P_NOTICE("GPS diconnected from port /=x ") return 0,0,"FAIL" end Log4Ienso.log.P_NOTICE("Ready to read GPS Port on /dev/ttyUSB1") nmeadata = `cat /dev/ttyUSB1` Log4Ienso.log.P_NOTICE("========Read /dev/ttyUSB1==============") Log4Ienso.log.P_NOTICE("NMEA : #{nmeadata}") nmeadata = nmeadata.to_s gprmc = nmeadata.match("GPRMC(.*)") gprmc = gprmc.to_s if !gprmc.nil? gprmc = gprmc.chomp.strip Log4Ienso.log.P_NOTICE("NMEA : #{gprmc}") end if !gprmc.nil? && !gprmc.empty? gprmca = gprmc.split(",") valid = gprmca[2] if valid == 'A' lat = gprmca[3] latd = gprmca[4] lat_decimal = convert_lat(lat,latd.strip) lng = gprmca[5] lngd = gprmca[6] lng_decimal = convert_lon(lng,lngd.strip) end end return lat_decimal, lng_decimal, "FIX" end def getGPSData2 satNo = 0 nmeadata= nil if !File.exist?('/dev/ttyUSB1') Log4Ienso.log.P_NOTICE("GPS diconnected from port /=x ") return 0,"FAIL" end Log4Ienso.log.P_NOTICE("Ready to read GPS Port on /dev/ttyUSB1") #k=Thread.new{ # nmeadata = `cat /dev/ttyUSB1 | head -20` # } #sleep (0.5) #k.kill if k != nil begin echo = Timeout::timeout(0.5){ nmeadata = `cat /dev/ttyUSB1 | head -20` } rescue Timeout::Error => e Log4Ienso.log.P_ERR("No Response from cat /dev/ttyUSB1 | head -20 !!!") nmeadata = nil end #nmeadata = `cat /dev/ttyUSB1 | head -20` Log4Ienso.log.P_NOTICE("========Read /dev/ttyUSB1==============") Log4Ienso.log.P_NOTICE("NMEA : #{nmeadata}") if( nmeadata == nil) Log4Ienso.log.P_ERR("NMEA returned nil so turn off gps") @quectelcmds.switchOffGPS() sleep (1.5) Log4Ienso.log.P_ERR("NMEA returned nil so turn on gps") @quectelcmds.switchOnGPS() sleep(0.2) return 0,"FAIL" else gpgsv = nmeadata.match("GPGSV(.*)") puts("----------- gpgsv=#{gpgsv}") if gpgsv != nil satcount = gpgsv[0].split(',') if gpgsv[0] != nil puts(satcount[3]) sat = satcount[3] if sat.to_i > 0 satNo = sat.to_i else satNo = 0 end puts("Sat visible are " + sat.to_s ) return satNo,"PASS" else return 0,"FAIL" end end end def getGPSData3() if !File.exist?('/dev/ttyUSB1') Log4Ienso.log.P_NOTICE("GPS diconnected from port /=x ") return 0,"FAIL" end Log4Ienso.log.P_NOTICE("Query GPS start...") #+QGPSLOC: 061951.0,3150.7223N,11711.9293E,0.7,62.2,2,0.0,0.0,0.0,110513,09 r = @quectelcmds.sendATCmdRaw("at+qgpsloc?") r = r.strip.chomp if r != nil Log4Ienso.log.P_NOTICE("Query GPS end...") if r != nil nmea = r.split(",") if nmea != nil if nmea.length < 3 return 0,0 end end timea = nmea[0] gtime =timea.split(":") lat = nmea[1].strip.chomp latx = lat[0..lat.length-2] latd = lat[-1..-1] latx = convert_lat(latx,latd) lng = nmea[2].strip.chomp lngx = lng[0..lng.length-2] lngd = lng[-1..-1] lngx = convert_lon(lngx,lngd) sat = nmea[10] errcode = nmea[11] end Log4Ienso.log.P_NOTICE(" satNO is " +sat.to_s ) return sat,"FIX" end # # stopGPS gets stuck , currently just returning from it # def stopGPS() @waitForGPS = Constant::GPS_ABORTED return r="FAIL" Log4Ienso.log.P_NOTICE(" >>> Stop GPS Function <<< ") if @quectelcmds == nil return "FAIL" end if isModemAvailable == true Log4Ienso.log.P_NOTICE(" >>> Stop gps sending AT command <<< ") r = @quectelcmds.sendATCmdRaw("at+qgpsend") Log4Ienso.log.P_NOTICE(" >>> Stopping GPS <<< ") sleep(0.3) #r = @quectelcmds.sendATCmdRaw("at+qgpsend") #r =`echo at+qgpsend > /dev/ttyUSB3` r = @quectelcmds.sendATCmdRaw("at+qgpsend") r = r.to_s r = r.chomp.strip if r != nil if r.include? "505" Log4Ienso.log.P_NOTICE("[GPS Session ended] " + r.to_s ) r="505" end if r.include? "504" Log4Ienso.log.P_NOTICE("[Session still active] " + r.to_s ) r="505" end end return r end def isModemAvailable portcount = `ls -l /dev/ttyUSB* | wc -l` if portcount.chomp.strip.to_i == @config.ltectrl.tty_port_count return true else return false end end def getCellularNetwork(iccid,env,starttype) if $hwimei == nil or $hwiccid == nil $hwimei,$hwiccid = @quectelcmds.getIMEIandICCID(starttype) Log4Ienso.log.P_NOTICE("The HW imei is #{$hwimei} amnd HW iccid is #{$hwiccid}" ) end if $hwiccid != iccid # happens when using testserver iccid = $hwiccid end Log4Ienso.log.P_NOTICE("finding cellular provider for #{iccid} and #{env.ltectrl.network.bellca.apn}" ) n=0 name=apn="" n=iccid[2..6] Log4Ienso.log.P_ERR("finding network for #{n}" ) if Constant::NETWORKS.include?n Log4Ienso.log.P_ERR("found sim card network #{Constant::NETWORKS[n]}" ) if Constant::NETWORKS[n] == "VERIZON" apn = env.ltectrl.network.verizon.apn name = "VERIZON" elsif Constant::NETWORKS[n] == "ROGERS_US" apn = env.ltectrl.networkrogers_us.apn name='Rogers US' elsif Constant::NETWORKS[n] == "BELL" apn = env.ltectrl.network.bellca.apn name = 'Bell Ca' elsif Constant::NETWORKS[n] == "ATT" apn = env.ltectrl.network.atandt.apn name="ATT" elsif Constant::NETWORKS[n] == "KPN" apn = env.ltectrl.network.kpn.apn name="KPN" else Log4Ienso.log.P_ERR("Rebooting because could not find out sim card provider" ) notify("modem/reboot") end end return name, apn end def get_provider(imsi, env,starttype) name = apn = nil firmware = @quectelcmds.getFirmwareVersion() $qtel_firmware = firmware pp = @quectelcmds.getUSANetwork($qtel_firmware) name,apn = getCellularNetwork(@iccid, env,starttype) if apn == nil #backup method for EC21 modem if ( pp == 'A' ) pvd = env.def_env.provider mcc = imsi[0..2] if pvd[mcc] != nil country = pvd[mcc]['country'] if(country == 'us') apn = env.ltectrl.network.atandt.apn name = "ATT" end end elsif ( pp == 'V' ) apn = env.ltectrl.network.verizon.apn name = 'VERIZON' end end return name, apn end # This methods handles events that were generated by EventSource that we registered to. # See new for a list of sources to which we register. def handle_event(event, data = nil) # Camera has finished capturing an image. if event =~ %r{lte/getting_ip_failed} Log4Ienso.log.P_ERR("#{Time.now.strftime("%H:%M:%S.%L")} ........ event lte/getting_ip_failed") notify("modem/getting_ip_failed") #Log4Ienso.log.P_ERR("#{Time.now.strftime("%H:%M:%S.%L")} ........ event lte/getting_ip_failed send modem/reboot") #notify("modem/reboot") elsif event =~ %r{lte/started} Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} ........ event lte/started") #notify("modem/started") elsif event =~ %r{qtel/lte_no_response} Log4Ienso.log.P_ERR("#{Time.now.strftime("%H:%M:%S.%L")} ........ event qtel/lte_no_response") notify("modem/getting_ip_failed") #temporary send ip_failed end end def chk_final_test_sw() if($final_test_flag || $final_test_finished_flag) return end path = "/media/photos/" + FINAL_TEST_FILE_NAME file = Dir[path] if(file.size == 0) Log4Ienso.log.P_NOTICE("????????????????? file is not there") else $final_test_flag = true @timer_lcd_off.start(false, 'never') disable_heart_bit() if ( ($imei != nil) && ($iccid != nil) ) $imei_iccid_valid = true Log4Ienso.log.P_NOTICE("///////// In chk_final_test_sw imei=#{$imei} and iccid=#{$iccid}") end Log4Ienso.log.P_NOTICE( "=============== Final Test file is in sdcard so start the final test routine") end end def startModemForLensFocusTest Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} [ConnectionManager] Starting Modem ") @modem = LteModem.new(@config) @modem.add_listener(self) modemval = @modem.enableModem(0) # this will create the data ports if( modemval.to_i == 5 ) Log4Ienso.log.P_INFO("Modem @modemval error #{@modemval}") returnval=5 else Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} [ConnectionManager] Modem - USB ports available ") if $imei == nil @quectelcmds = QuectelATCommands.new(@modem.getCommandPort,@config.control.log_name,@modem.getLteConfigFile) x = @quectelcmds.getIMEI() $imei = x.tr("^0-9", '') # just need the numbers returnval=0 if $imei != nil end end return returnval end def waitForGPSFixBlocking(fixCount, waitCount = 0, seconds = 30) gpsFixWaitCount = waitCount # Aeronix: We really would like to delay here on a COLD::BOOT to give the gps time to get a fix # before the data is sent to the server. Otherwise the website will not get updated for # possibly a day to get the fix. # possibly a day to get the fix. loop do if $gpsTTFFcnt > fixCount Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} blockWaitForGPSFix: fix increment") break end gpsFixWaitCount += 1 sleep (1) if gpsFixWaitCount > 30 Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} blockWaitForGPSFix: fix timeout") break end end end def startNetworkConnection(starttype,counter) init() @threadcount=0 @globalfail = 0 returnval=1 dtcheckyr=`date +%Y` #get the year dtcheckyr = dtcheckyr.chomp.strip dtcheckmo=`date +%m` #get the month dtcheckmo = dtcheckmo.chomp.strip dtcheckda=`date +%d` #get the day dtcheckda = dtcheckda.chomp.strip Log4Ienso.log.P_YELLOW("\n#{Time.now.strftime("%H:%M:%S.%L")} [ConnectionManager] Starting Modem, starttype=#{starttype}\n") @modem = LteModem.new(@config) @modem.add_listener(self) notify("modem/started") modemval = @modem.enableModem(starttype) if $model == "impulse" # this will create the data ports modemval = @modem.enableModemBG96(starttype) if $model == "primos" if( modemval.to_i == 5 ) Log4Ienso.log.P_INFO("Modem @modemval error #{@modemval}") Log4Ienso.log.P_ERR("#{Time.now.strftime("%H:%M:%S.%L")} Modem setup failed ... lets sleep") notify("modem/reboot") returnval=5 else notify("modem/usbconnected") Log4Ienso.log.P_CLEAN("#{Time.now.strftime("%H:%M:%S.%L")} [ConnectionManager] Modem - USB ports available \n") @modemportsavailable = 1 if starttype == Constant::COLD_BOOT Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} [ConnectionManager] In cold boot Sleeping another 25 seconds before reading modem ") sleep(25) #on first boot give some extra time to stabalize end @quectelcmds = QuectelATCommands.new(@modem.getCommandPort,@config.control.log_name,@modem.getLteConfigFile) @quectelcmds.add_listener(self) if starttype == Constant::COLD_BOOT || counter < 3 r = @quectelcmds.sendATCmdRaw("ate0") # Aeronix - moved these command here from sleep call r = @quectelcmds.sendATCmdRaw("AT+QCFG=\"urc/ri/ring\",\"off\"") r = @quectelcmds.sendATCmdRaw("AT+QCFG=\"urc/ri/other\",\"off\"") r = @quectelcmds.sendATCmdRaw("AT+QCFG=\"urc/ri/smsincoming\",\"pulse\",150,3") r = @quectelcmds.sendATCmdRaw("AT+QCFG=\"risignaltype\",\"physical\"") # Aeronix; this call always fails and does not seem to be supported by the modem # @quectelcmds.sendATCmdRaw("at+cgml=2,2") #prevent storage of sms messages, required on every boot as not stored on quectel @quectelcmds.getAPNList if !$final_test_flag end if !$final_test_flag checkSimRegnStatus(0) else r = @quectelcmds.stopTxRx end while ((@imei == nil) && (@iccid == nil)) if $testserver == nil @imei,@iccid = @quectelcmds.getIMEIandICCID(starttype) else chk_test_server_enabled Log4Ienso.log.P_NOTICE("getting imei #{$imei} and iccid #{$iccid} for #{$testserver} ") @imei = $imei @iccid = $iccid end if ((@imei == nil) && (@iccid == nil)) Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} WARNING: ------------------------------------------------- No Value for IMEI and ICCID - Trying to obtain them , next attempt") sleep(3) else Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} Obtained iccid=#{@iccid} and imei=#{@imei}") if (@imsi == nil) @imsi = @quectelcmds.getIMSI() Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} Obtained imsi=#{@imsi} ") if (@imsi != nil) $imsi = @imsi if $model == "impulse" name, apn = get_provider(@imsi, @config,starttype ) $networkname = name setConnectionParametersImpulse(apn,@config,name,starttype) if !$final_test_flag end if $model == "primos" name,apn = getCellularNetwork(@iccid, @config,starttype) $networkname = name setConnectionParametersPrimos(apn,@config,name) end fixOmaSolution1() end end end end if $final_test_flag setLocalTime() return 0 end if dtcheckyr == "1970" || starttype == Constant::COLD_BOOT || ( dtcheckyr == "2018" && dtcheckmo == "01" && dtcheckda == "01") Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} Base time found, need to set correct time") #system("/opt/wtc2.0/src/modemtime.sh") modemTime() #@quectelcmds.setLocalTime() setLocalTime() end # on boot try to set local time again wihhout the retry mechanism required for rare bug in QLTS=2 #QLTS=2 on rare occassions sends wrong time, usually UTC time. if starttype == Constant::COLD_BOOT setLocalTime() else setLocalTime(1) end Log4Ienso.log.P_ERR("#{Time.now.strftime("%H:%M:%S.%L")} Attempting network connection ") status = @modem.connect(@network) if $model == "impulse" status = @modem.connectBG96(@network) if $model == "primos" Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} Return value from IP network setup is " + status.to_s) #notify("modem/getting_ip_failed") if status != 0 if(status != 0) Log4Ienso.log.P_INFO("Modem status error #{status}") returnval =status notify("modem/reboot") end if status == 0 @modemconnected = 1 if @imei == nil || @iccid == nil @quectelcmds = QuectelATCommands.new(@modem.getCommandPort,@config.control.log_name,@modem.getLteConfigFile) @quectelcmds.add_listener(self) if $testserver == nil @imei,@iccid = @quectelcmds.getIMEIandICCID(starttype) else @imei = $imei @iccid = $iccid end Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} Modem booting OK, got IMEI #{@imei} and ICCID #{@iccid} after network connection") end if !$final_test_flag checkSimRegnStatus(1) end if @imei !=nil and @iccid !=nil if $testserver == nil @apiendpoint = @modem.getAPIEndPoint else Log4Ienso.log.P_NOTICE("***** connecting to test server ******") Log4Ienso.log.P_NOTICE("#{$testserver}") @apiendpoint = $testserver end @sessiontokenfile = @modem.getSessionTokenFile portcount = `ls -l /dev/ttyUSB* | wc -l` if portcount.chomp.strip.to_i == @config.ltectrl.tty_port_count Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} 5 ports created") @connected=1 count=0 Log4Ienso.log.P_INFO("THE TIME ON STARTUP IS >>> " + dtcheckyr.to_s) if dtcheckyr == "1970" || starttype == Constant::COLD_BOOT ||( dtcheckyr == "2018" && dtcheckmo == "01" && dtcheckda == "01") || $dailyAlertTimeUpdate == true Log4Ienso.log.P_INFO("Base time found, need to set correct time") #system("/opt/wtc2.0/src/modemtime.sh") modemTime() #@quectelcmds.setLocalTime() setLocalTime() $dailyAlertTimeUpdate = false end notify("modem/connected") else Log4Ienso.log.P_INFO("error port count #{portcount} [#{@config.ltectrl.tty_port_count}]") notify("modem/reboot") end returnval=0 else returnval=1 end end end returnval end def checkSimRegnStatus(attempt) nettype = @quectelcmds.getNetworkDetails(Constant::NETWORK_TYPE) if nettype != nil y = nettype.split(',') @networktype = y[2] if y[2] != nil Log4Ienso.log.P_NOTICE("Access Type: #{y[0]}") if y[0] != nil Log4Ienso.log.P_NOTICE("Operator: #{y[1]} ") if y[1] != nil Log4Ienso.log.P_NOTICE("Band: #{y[2]} ") if y[2] != nil Log4Ienso.log.P_NOTICE("Channel:#{y[3]} ") if y[3] != nil end begin rstate = @quectelcmds.getNetworkDetails(Constant::NETWORK_REGN_STATE) Log4Ienso.log.P_NOTICE("network state is #{rstate}") y = rstate.split(",") if y[1].to_s.strip == "0" Log4Ienso.log.P_NOTICE("Not looking for network - some problem with network or in airplane mode") @network_state_desc = "Err 0, cannot connect" @networkstate = 0 if attempt > 0 notify("modem/reboot") return 1 end end if y[1].to_s.strip == "1" Log4Ienso.log.P_NOTICE("Registered with network -HOME NETWORK") @network_state_desc = "Home net-connected" @networkstate = 1 $nonetworkregistercount = 0 end if y[1].to_s.strip == "2" Log4Ienso.log.P_NOTICE("Looking to get registered with a network") @network_state_desc = "Err 2, Trying to register" @networkstate = 2 $nonetworkregistercount+=1 if $nonetworkregistercount > 3 firmware = @quectelcmds.getFirmwareVersion() networkid = @quectelcmds.getUSANetwork(firmware) if networkid=='V' c=0 while c < 3 fixSim #verizon sim cards when roaming can get dergistered sleep 0.5 c+=1 end @quectelcmds.shutDownOrRebootModem end $nonetworkregistercount = 0 end if attempt > 0 notify("modem/reboot") return 1 end end if y[1].to_s.strip == "3" Log4Ienso.log.P_NOTICE("Sim card regn is declined.") @network_state_desc = "Err 3, Declined - AP" @networkstate = 3 if attempt > 0 notify("modem/reboot") return 1 end end if y[1].to_s.strip == "4" Log4Ienso.log.P_NOTICE("Not looking for network - unknown error ") @network_state_desc = "Err 4, Unknown" @networkstate = 4 if attempt > 0 notify("modem/reboot") return 1 end end if y[1].to_s.strip == "5" Log4Ienso.log.P_NOTICE("Registered with network - ROAMING") @network_state_desc = "Connected - Roaming" @networkstate = 5 $nonetworkregistercount = 0 end rescue Log4Ienso.log.P_NOTICE("Error in reading network registeration state") end end def startNetworkConnectionBoardTest(starttype,counter) @threadcount=0 @globalfail = 0 returnval=1 dtcheckyr=`date +%Y` #get the year dtcheckyr = dtcheckyr.chomp.strip dtcheckmo=`date +%m` #get the month dtcheckmo = dtcheckmo.chomp.strip dtcheckda=`date +%d` #get the day dtcheckda = dtcheckda.chomp.strip Log4Ienso.log.P_ERR("#{Time.now.strftime("%H:%M:%S.%L")} [ConnectionManager] Starting Modem, starttype=#{starttype}") @modem = LteModem.new(@config) @modem.add_listener(self) notify("modem/started") modemval = @modem.enableModem(starttype) if $model == "impulse" # this will create the data ports modemval = @modem.enableModemBG96(starttype) if $model == "primos" if( modemval.to_i == 5 ) Log4Ienso.log.P_INFO("Modem @modemval error #{@modemval}") Log4Ienso.log.P_ERR("#{Time.now.strftime("%H:%M:%S.%L")} Modem setup failed ... lets sleep") notify("modem/reboot") returnval=5 else notify("modem/usbconnected") Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} [ConnectionManager] Modem - USB ports available ") @modemportsavailable = 1 if starttype == Constant::COLD_BOOT Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} [ConnectionManager] In cold boot Sleeping another 15 seconds before reading modem ") sleep(1) #on first boot give some extra time to stabalize end @quectelcmds = QuectelATCommands.new(@modem.getCommandPort,@config.control.log_name,@modem.getLteConfigFile) @quectelcmds.add_listener(self) if starttype == Constant::COLD_BOOT r = @quectelcmds.sendATCmdRaw("ate0") sleep 0.5 r = @quectelcmds.stopTxRx sleep 0.5 r = @quectelcmds.stopTxRx end #@quectelcmds.getAPNList if starttype == Constant::COLD_BOOT #only for debugging cntr = 0 while cntr < 5 cntr += 1 Log4Ienso.log.P_ERR("#{Time.now.strftime("%H:%M:%S.%L")} cntr=#{cntr}") if (@imei == nil) Log4Ienso.log.P_ERR("#{Time.now.strftime("%H:%M:%S.%L")} WARNING: --------- No Value for IMEI Trying to obtain them , next attempt") @imei = @quectelcmds.execATCmdIMEI() else Log4Ienso.log.P_CLEAN("#{Time.now.strftime("%H:%M:%S.%L")} Obtained imei=#{@imei}\n") end if (@iccid == nil) Log4Ienso.log.P_ERR("#{Time.now.strftime("%H:%M:%S.%L")} WARNING: -------- No Value for ICCID - Trying to obtain them , next attempt") @iccid = @quectelcmds.execATCmdICCID() else Log4Ienso.log.P_CLEAN("#{Time.now.strftime("%H:%M:%S.%L")} Obtained iccid=#{@iccid}\n ") end if ((@imei == nil) || (@iccid == nil)) sleep 2 next else returnval = 0 break end end Log4Ienso.log.P_MAGENTA("#{Time.now.strftime("%H:%M:%S.%L")} got imei and iccid ") end returnval end def modemTime() r = @quectelcmds.sendATCmdRaw("at+ctzu=3") r = @quectelcmds.sendATCmdRaw("at+ctzr=2") end def isTakePicSMS count = 0 r=nil begin if @quectelcmds == nil @quectelcmds = QuectelATCommands.new(@modem.getCommandPort,@config.control.log_name,@modem.getLteConfigFile) end @quectelcmds.sendATCmdRaw("at+cmgf=1") @quectelcmds.sendATCmdRaw("at+cmgl='REC UNREAD'") while r==nil r = @quectelcmds.sendATCmdRaw("at+cmgl") count+=1 break if count > 3 sleep 0.3 end if r != nil r=r.strip.chomp Log4Ienso.log.P_MAGENTA("#{Time.now.strftime("%H:%M:%S.%L")} sms is #{r} ") if r.include? "BUSHNELL-captureimage" #removed check because many valid sms are without the value due to at cmds return true end end return false rescue Log4Ienso.log.P_MAGENTA("#{Time.now.strftime("%H:%M:%S.%L")} Failed to check sms ") end end def startUpload begin @timecontrol.lock @uploadStartTime = Time.now @timecontrol.unlock notify("modem/startingupload") Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} Starting upload") ensure #@accesscontrol.unlock end end # using AT commands, does not work all the time def shutDownOrRebootModem Log4Ienso.log.P_INFO("Rebooting or shutting down modem") @quectelcmds.shutDownOrRebootModem end def endUpload begin @accesscontrol.lock @threadcount-=1 @accesscontrol.unlock #@timecontrol.lock # @uploadStartTime = Time.now #@timecontrol.unlock if @threadcount <= 1 notify("modem/finishedupload") Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} upload Thumb finished") Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} Ending upload") end Log4Ienso.log.P_ERR("Falling thread count is "+ @threadcount.to_s) ensure #@accesscontrol.unlock end end def updateNetworkState begin if @readytosleep==0 #modem sleep should not have started if @modem.getNetworkAssignedIPAddress == nil notify("modem/reboot") end r =`ls -la /dev/ttyUSB* | head -3 | tail -1 |cut -c 1` if r.chomp == "-" `rm -rf /dev/ttyUSB*` Log4Ienso.log.P_NOTICE("fake port") end r = `ls -l /dev/ttyUSB* | wc -l` if r.chomp.strip.to_i != @config.ltectrl.tty_port_count notify("modem/reboot") Log4Ienso.log.P_NOTICE("port 1") end if @uploadStartTime != 0 if Time.now - @uploadStartTime > 30 # more than 30 sec to upload Log4Ienso.log.P_NOTICE("time exceeded") notify("modem/reboot") end end end rescue Log4Ienso.log.P_NOTICE("network state err") notify("modem/reboot") end end def getStatusCode return @zipitStatusCode end def getFirmWareManifest if @manifest != nil temp = @manifest.to_json temp = @manifest.gsub("=>", ":") @manifest = nil return temp end if @zipit == nil @zipit = ZipItRestApi.new(@imei,@iccid,@apiendpoint,@sessiontokenfile,@config) r=@zipit.register @zipitStatusCode = @zipit.getStatusCode end return @zipit.getFirmWareManifest end def checkToken if @zipitStatusCode.include? "401" Log4Ienso.log.P_NOTICE("401 condition found, overriding it temporarily") @zipit = nil end if @zipit == nil @zipit = ZipItRestApi.new(@imei,@iccid,@apiendpoint,@sessiontokenfile,@config) end Log4Ienso.log.P_INFO("checking token") r=@zipit.register @zipitStatusCode = @zipit.getStatusCode end def uploadThumb(thumb) exit_code=1 begin startUpload() Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} upload Thumb started") Log4Ienso.log.P_INFO("imei=#{@imei} ,iccid=#{@iccid}, apiendpoint=#{@apiendpoint} @sessiontokenfile=#{@sessiontokenfile}") @accesscontrol.lock @threadcount+=1 @accesscontrol.unlock if @zipit == nil @zipit = ZipItRestApi.new(@imei,@iccid,@apiendpoint,@sessiontokenfile,@config) Log4Ienso.log.P_INFO("checking token") r=@zipit.register @zipitStatusCode = @zipit.getStatusCode else Log4Ienso.log.P_INFO("Not checking token") end if @accesscontrol.synchronize{@globalfail} == 0 Log4Ienso.log.P_INFO("imei=#{@imei} ,iccid=#{@iccid}, apiendpoint=#{@apiendpoint} @sessiontokenfile=#{@sessiontokenfile}") Log4Ienso.log.P_INFO("return val is "+r.to_s) Log4Ienso.log.P_CLEAN("#{Time.now.strftime("%H:%M:%S.%L")} rising thread count is " + @threadcount.to_s + " @zipit.getThumbnailCDN starts\n") cdn_url,cdn_host,id = @zipit.getThumbnailCDN(thumb) Log4Ienso.log.P_CLEAN("#{Time.now.strftime("%H:%M:%S.%L")} rising thread count is " + @threadcount.to_s + " @zipit.getThumbnailCDN ends and starts upload\n") Log4Ienso.log.P_INFO(cdn_url) Log4Ienso.log.P_INFO(cdn_host) #notify("modem/ignore_pir") exit_code=@zipit.uploadThumbnail(thumb,cdn_url,cdn_host,id) Log4Ienso.log.P_CLEAN("#{Time.now.strftime("%H:%M:%S.%L")} rising thread count is " + @threadcount.to_s + "@zipit.uploadThumbnail ends\n") #notify("modem/resume_pir") endUpload end return exit_code rescue Exception => e @accesscontrol.lock @globalfail = 1 @accesscontrol.unlock Log4Ienso.log.P_ERR(e.backtrace) notify("modem/reboot") ensure @zipitStatusCode = @zipit.getStatusCode if @zipit != nil return exit_code #@accesscontrol.unlock end end def uploadHiRes( hiresfile,id ) startUpload @accesscontrol.lock @threadcount+=1 @accesscontrol.unlock extn="" fname = File.basename(hiresfile) if fname.include? "P.jpg" extn=fname.sub("P.jpg",".jpg") else extn=fname.sub("V.jpg",".mp4") end hiresfile = Constant::HIRES_PATH + extn Log4Ienso.log.P_INFO("Loading..... "+ hiresfile) if File.exists?(hiresfile) cdn_url,cdn_host= @zipit.getImageOrVideoCDN(hiresfile,id) Log4Ienso.log.P_INFO(cdn_url) Log4Ienso.log.P_INFO(cdn_host) exit_code = @zipit.uploadHiResImageOrVideo(hiresfile,cdn_url,cdn_host,id) else @zipit.reportFileNotFound(id) end endUpload end def setGPSState(val) @waitForGPS = val end def SetIsGPSSessionActive(val) @isGPSSessionActive = val end def setIsOTASessionActive(val) @isOTASessionActive = val end def startModemSleepNormal(startmode,movielen) if @isOTASessionActive == true Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} Will not sleep .. OTA is active") return end while $video_recording == true @vidrecstarttime = Time.now if @vidrecstarttime==0 tdiff = Time.now - @vidrecstarttime Log4Ienso.log.P_YELLOW("#{Time.now.strftime("%H:%M:%S.%L")} Will not sleep .. video recording is on #{tdiff}") if movielen >15 or tdiff > 20 Log4Ienso.log.P_YELLOW("#{Time.now.strftime("%H:%M:%S.%L")} Going to sleep , video over cutoff seconds #{tdiff}") break end sleep 1 end if @isNextPhotoAvailable == true Log4Ienso.log.P_NOTICE("early check - more photos to upload ...") notify("modem/continueupload") return end Log4Ienso.log.P_CLEAN("-----------------------------------------------------------------------------------------------------\n") Log4Ienso.log.P_ERR("#{Time.now.strftime("%H:%M:%S.%L")} ''' startModemSleepNormal ''' routine started\n") Log4Ienso.log.P_CLEAN("-----------------------------------------------------------------------------------------------------\n") begin uploadfiles = [] if @zipit == nil @zipit = ZipItRestApi.new(@imei,@iccid,@apiendpoint,@sessiontokenfile,@config) r=@zipit.register end if @zipit != nil remote_requests = @zipit.getCommands(startmode) uploadfiles,configchanged,captureimage,deleteall, uploadfrequency, uploadloglevel,uploadlogurl,activatewifi,firmware, trackingstatus, changeddata = @zipit.parseServerCommand(remote_requests) uploadfilecount = 0 ntime = 0 if uploadfiles != nil $is_ffmeg_started = true uploadfilecount = uploadfiles.length if uploadfilecount > 0 while $video_recording == true Log4Ienso.log.P_YELLOW("#{Time.now.strftime("%H:%M:%S.%L")} Will not sleep .. video recording is on") sleep 1 end ntime = Constant::FFMPEG_ENCODING_TIME * ( uploadfilecount ) time_extn = {:extntime=>ntime} notify("system/changecutofftime", time_extn) end if uploadfiles.length > 0 uploadfiles.each{ |x| uploadHiRes(x["name"],x["id"]) } end $is_ffmeg_started = false Log4Ienso.log.P_YELLOW("#{Time.now.strftime("%H:%M:%S.%L")} Hi Res files to upload: " +uploadfiles.to_s) end Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} config changed is " + configchanged.to_s) notify("menu/refresh") if configchanged.to_i == 1 notify("camera/takepic") if captureimage == true notify("camera/deleteall") if deleteall == true notify("camera/wifion") if activatewifi == true notify("camera/wifioff") if activatewifi == false if changeddata['imgresolution'] != "false" Log4Ienso.log.P_NOTICE("imgresolution data has changed") msgval={ :imgresolution => changeddata['imgresolution'] } notify("http/imgresolution",msgval) end if changeddata['capture_mode'] != "false" Log4Ienso.log.P_NOTICE("capture_mode data has changed") msgval={ :capture_mode => changeddata['capture_mode'] } notify("http/capture_mode",msgval) end if changeddata['movieresolution'] != "false" Log4Ienso.log.P_NOTICE("movieresolution data has changed") msgval={ :movieresolution => changeddata['movieresolution'] } notify("http/movieresolution",msgval) end if changeddata['pirmode'] != "false" Log4Ienso.log.P_NOTICE("pirmode data has changed") msgval={ :pirmode => changeddata['pirmode'] } notify("http/pirmode",msgval) end if changeddata['pirsensitivity'] != "false" Log4Ienso.log.P_NOTICE("pirsensitivity data has changed") msgval={ :pirsensitivity => changeddata['pirsensitivity'] } notify("http/pirsensitivity",msgval) end if changeddata['timeofoperation'] != "false" Log4Ienso.log.P_NOTICE("timeofoperation data has changed") msgval={ :timeofoperation => changeddata['timeofoperation'] } notify("http/timeofoperation",msgval) end if changeddata['fieldscan'] != "false" Log4Ienso.log.P_NOTICE("fieldscan data has changed") msgval={ :fieldscan => changeddata['fieldscan'] } notify("http/fieldscan",msgval) end if changeddata['pirdelay'] != "false" Log4Ienso.log.P_NOTICE("pirdelay has changed") msgval={ :pirdelay => changeddata['pirdelay'] } notify("http/pirdelay",msgval) end if changeddata['ledintensity'] != "false" Log4Ienso.log.P_NOTICE("ledintensity has changed") msgval={ :ledintensity => changeddata['ledintensity'] } notify("http/ledintensity",msgval) end if changeddata['movielength'] != "false" Log4Ienso.log.P_NOTICE("movielength has changed") msgval={ :movielength => changeddata['movielength'] } notify("http/movielength",msgval) end if changeddata['shutterspeed'] != "false" Log4Ienso.log.P_NOTICE("shutterspeed has changed") msgval={ :shutterspeed => changeddata['shutterspeed'] } notify("http/shutterspeed",msgval) end if changeddata['showtimestamp'] != "false" Log4Ienso.log.P_NOTICE("showtimestamp has changed") msgval={ :showtimestamp => changeddata['showtimestamp'] } notify("http/showtimestamp",msgval) end if changeddata['tracking'] == "off" #|| trackingstatus == false Log4Ienso.log.P_NOTICE("cm: tracking switched off") msgval={ :tracking => false } notify("http/tracking",msgval) @trackingstate = 0 @trackingstatus = 0 $tracking_enabled_oncamera = false end if changeddata['tracking'] == "on" #|| trackingstatus == true Log4Ienso.log.P_NOTICE("cm: tracking switched on") msgval={ :tracking => true } notify("http/tracking",msgval) @trackingstate = 0 @trackingstatus = 1 $tracking_enabled_oncamera = true end Log4Ienso.log.P_NOTICE("CAMERA STATUS VALUE IS #{@cameraStatusUpdated} and statusv2session #{@sentthissession}") if @cameraStatusUpdated == true || activatewifi == true Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} setting camera status") if activatewifi == true #let the wifi come up as we need to send the SSID @wifistate = 1 sleep(4) #let the wifi come up as to send the SSID end if $tracking_enabled_oncamera == true @trackingstatus = 1 end if @sentthissession == false @zipit.setStatus(@storageused,@storagesize,@battery,@latitude,@longitude,@rssi,@gpstime ,@trackingstate , @wifistate ) Log4Ienso.log.P_NOTICE("Sending status V2") @zipit.setConfigStatus(@storageused,@storagesize,@battery,@latitude,@longitude,@rssi,@trackingstatus) #to do this needs to be sent only once at start of tracking @sentthissession = true end @cameraStatusUpdated = false end if $menu_values_changed == true if @sentthissession == false @zipit.setConfigStatus(@storageused,@storagesize,@battery,@latitude,@longitude,@rssi,@trackingstatus) @sentthissession = true end $menu_values_changed = false end # if camera config has changed on the camerarm co #@zipit.setConfigStatus if uploadlogurl != nil Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} Uploading log file to #{uploadlogurl}") @zipit.uploadLogFile(uploadlogurl) end if firmware != nil if firmware == true Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} New Production Firmware to install") notify("camera/firmwareupdate") else Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} Test Firmware to install") notify("camera/firmwareupdate") @manifest = firmware.to_s end end Log4Ienso.log.P_INFO(remote_requests) Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} the remote server commands have been completed ") end rescue Exception => e Log4Ienso.log.P_ERR(e.backtrace) ensure $is_ffmeg_started = false #@cutoffnotification = false Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} In ensure block") waitstarttime = Time.now waitchecktime = 0 #while @threadcount > 0 do # Log4Ienso.log.P_NOTICE("#######################################") # Log4Ienso.log.P_NOTICE("waiting for the uploads to complete...") # Log4Ienso.log.P_NOTICE("#######################################") # waitchecktime = Time.now - waitstarttime.to_i #if waitchecktime.to_i > 5 # break #end # sleep 0.2 #end if $final_test_flag == true Log4Ienso.log.P_NOTICE("Cannot sleep - $final_test_flag == true ...") return end if activatewifi == true Log4Ienso.log.P_NOTICE("Cannot sleep - hotspot on...") return end if @waitForGPS > Constant::GPS_SWITCHED_OFF Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} Cannot sleep because GPS is on") return end if @isGPSSessionActive == true Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} Will not sleep .. GPS is active") return end if @isOTASessionActive == true Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} Will not sleep .. OTA is active") return end if @isNextPhotoAvailable == true || captureimage == true Log4Ienso.log.P_NOTICE("more photos to upload ...") notify("modem/continueupload") return end notify("modem/sleeping") sleep 0.1 @readytosleep=1 Log4Ienso.log.P_NOTICE("#######################################") Log4Ienso.log.P_NOTICE("#######################################") Log4Ienso.log.P_NOTICE("#######################################") Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} starting sleep process ...") Log4Ienso.log.P_NOTICE("#######################################") Log4Ienso.log.P_NOTICE("#######################################") Log4Ienso.log.P_NOTICE("#######################################") @zipit = nil #@modem.startSleep if @modem != nil sleepModem end end def startModemSleepAbort @zipit = nil #@modem.startSleep if @modem != nil sleepModem end def cameraStatusSetandUpdate(storageused,storagesize,battery,latitude,longitude,rssi,gpstime,trackingstate,wifistate, is_statusv2_change ) @storageused = storageused @storagesize = storagesize @battery = battery @latitude = latitude @longitude = longitude @rssi = rssi @gpstime = gpstime @trackingstate = trackingstate @wifistate = wifistate @cameraStatusUpdated = true if is_statusv2_change == true end def updateGPSFromFTP validSecs = gpsAidingDataValid() if validSecs < 0 return false end validDays = validSecs.to_f / 60 / 60 / 24 if validDays > 6 return true end ftpserver = @config.ftp.servername ftpuser = @config.ftp.username ftp_password= @config.ftp.password provider = $networkname if (provider == 'ROGERS-US') apn = @config.ltectrl.network.rogers_us.apn pdp = @config.ltectrl.network.rogers_us.pdp elsif (provider == 'VERIZON') apn = @config.ltectrl.network.verizon.apn pdp = @config.ltectrl.network.verizon.pdp elsif (provider == 'ATT') apn = @config.ltectrl.network.atandt.apn pdp = @config.ltectrl.network.atandt.pdp elsif (provider == 'ROGERS-CAN') apn = @config.ltectrl.network.rogers_can.apn pdp = @config.ltectrl.network.rogers_can.pdp elsif (provider == 'KPN') apn = @config.ltectrl.network.kpn.apn pdp = @config.ltectrl.network.kpm.pdp else apn = @config.ltectrl.network.rogers_can.apn pdp = @config.ltectrl.network.rogers_can.pdp end @quectelcmds = QuectelATCommands.new(@modem.getCommandPort,@config.control.log_name,@modem.getLteConfigFile) if @quectelcmds == nil @quectelcmds.add_listener(self) return @quectelcmds.updateGPSFromFTP(ftpserver, ftpuser, ftp_password, apn, pdp) end def setNextPhotoAvailable(val) @isNextPhotoAvailable = val end # verizon roaming sims de-register fix def fixSim r = @quectelcmds.fixSim return r end # disable tx/rx def stopTxRx if @modemconnected == 1 r = @quectelcmds.stopTxRx return "Stopped Tx/Rx" end return "Modem not avail" end #enable tx/rx def startTxRx if @modemconnected == 1 r = @quectelcmds.startTxRx return "Started Tx/Rx" end return "Modem not avail" end # used by Bushnell for testing only def chk_test_server_enabled if $testserver != nil #check end path = "/media/photos/" + Constant::TEST_SERVER_FILE if File.exist?(path) Log4Ienso.log.P_NOTICE("Pointing to test server") data = `cat #{path}` dt = data.split(";") prodserver = "https://wirelesstrophycam.com:8001" if dt[2] != nil $imei = dt[0] $iccid = dt[1] $testserver = dt[2].chomp.strip end if prodserver == $testserver Log4Ienso.log.P_NOTICE("Illegal assignment to Prod server, setting back to default dev server") $testserver ="https://test2.wirelesstrophycam.com:8001" end Log4Ienso.log.P_NOTICE("Pointing to test server #{$imei} #{$iccid} #{$testserver}") else Log4Ienso.log.P_NOTICE("--- Pointing to default server ---") $testserver = nil end end def getIPaddr return @modem.getNetworkAssignedIPAddress end ############## return nil if not succesful ############# def getRSSI(mode = 0) r= nil if @modemportsavailable == 1 begin r = @quectelcmds.getSignalStrength(mode) rescue Exception => e Log4Ienso.log.P_ERR(e.backtrace) ensure return r end else return nil end end def isConnected return @network_state_desc end def self.setConnectionParameters(provider,attr) `cp /opt/wtc2.0/src/ppp_scripts/q* /etc/ppp/peers/` sleep(0.4) if (provider == 'ROGERS-US') apn = attr.ltectrl.network.rogers_us.apn elsif (provider == 'VERIZON') apn = attr.ltectrl.network.verizon.apn elsif (provider == 'ATT') apn = attr.ltectrl.network.atandt.apn elsif (provider == 'ROGERS-CAN') apn = attr.ltectrl.network.rogers_can.apn elsif (provider == 'KPN') apn = attr.ltectrl.network.kpn.apn else apn = attr.ltectrl.network.rogers_can.apn end dev = attr.ltectrl.tty_data[/(?:.(?!\/))+$/] dev=dev[1..dev.length] `sed -i "s/config_var_port/#{dev}/g" /etc/ppp/peers/quectel-ppp` `sed -i "s/config_var_apn/#{apn}/g" /etc/ppp/peers/quectel-chat-connect` if(provider == 'VERIZON') dialcode = attr.ltectrl.network.verizon.dialcode `sed -i "s/config_var_dialcode/#{dialcode}/g" /etc/ppp/peers/quectel-chat-connect` `sed -i '/CGDCONT/d' /etc/ppp/peers/quectel-chat-connect` end end def setConnectionParametersPrimos(apn,attr,name) napn = `cat /etc/qmi-network.conf | head -1 | awk -F"=" '{print $2}'` if napn.strip != apn.strip `sed 's/.*APN.*/APN=#{apn}/' /etc/qmi-network.conf` Log4Ienso.log.P_INFO("Changing apn to #{apn}") else Log4Ienso.log.P_INFO("APN is already correct as #{apn}") end end def setConnectionParametersImpulse(apn,attr,name,starttype) `cp /opt/wtc2.0/src/ppp_scripts/q* /etc/ppp/peers/` sleep(0.4) dev = attr.ltectrl.tty_data[/(?:.(?!\/))+$/] puts ("dev=#{dev}, apn=#{apn}") Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} Setting connection parameters dev=#{dev}, apn=#{apn}") dev=dev[1..dev.length] `sed -i "s/config_var_port/#{dev}/g" /etc/ppp/peers/quectel-ppp` `sed -i "s/config_var_apn/#{apn}/g" /etc/ppp/peers/quectel-chat-connect` dialcode = 'ATD*99#' if(name == 'VERIZON') dialcode = attr.ltectrl.network.verizon.dialcode `sed -i "s/config_var_dialcode/#{dialcode}/g" /etc/ppp/peers/quectel-chat-connect` `sed -i '/CGDCONT/d' /etc/ppp/peers/quectel-chat-connect` qfirmware = nil qfirmware = @quectelcmds.getFirmwareVersion() begin if qfirmware != nil qfirmware = qfirmware.strip.chomp qfirmware = qfirmware[0..15] if qfirmware == "EC21VFAR02A13M4G" and ( starttype == Constant::COLD_BOOT or $verizonfimwarebugfix == false) Log4Ienso.log.P_INFO("Adding CGDCONT value (context 1) for Verizon Quectel firmware #{qfirmware}") `sed -i '9 a OK AT+CGDCONT=1,"IPV4V6","VZWIMS","0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0",0,0,0,0' /etc/ppp/peers/quectel-chat-connect` $verizonfimwarebugfix =true end end rescue Log4Ienso.log.P_INFO("Could not get firmware version") end else `sed -i "s/config_var_dialcode/#{dialcode}/g" /etc/ppp/peers/quectel-chat-connect` end end end if __FILE__ == $0 begin @connmanager = ConnectionManager.new(YAML.load(File.read("/opt/wtc2.0/src/wtc2_config_v0.0.2-a.yaml")).to_hashugar) Log4Ienso.log.P_INFO("ready to enable modem") ConnectionManager.setConnectionParameters('ROGERS-US',YAML.load(File.read("/opt/wtc2.0/src/wtc2_config_v0.0.2-a.yaml")).to_hashugar) status = @connmanager.startNetworkConnection(0,1) if status== 0 Log4Ienso.log.P_INFO("connected") else Log4Ienso.log.P_ERR("failed to connect and code is "+status.to_s) end rescue Exception => e Log4Ienso.log.P_ERR("Exception: #{e}") Log4Ienso.log.P_ERR(e.backtrace) end end opt/wtc2.0/src/pulse.sh0000755000175200017520000000146613557057144015413 0ustar bushnellbushnell#!/bin/sh GPIO=/sys/class/gpio/gpio116/ if [ ! -d $GPIO ] then echo 116 > /sys/class/gpio/export fi echo out > $GPIO/direction echo 1 > $GPIO/value GPIO=/sys/class/gpio/gpio147/ if [ ! -d $GPIO ] then echo 147 > /sys/class/gpio/export fi echo out > $GPIO/direction echo 1 > $GPIO/value GPIO=/sys/class/gpio/gpio140/ if [ ! -d $GPIO ] then echo 140 > /sys/class/gpio/export fi echo 1 > $GPIO/value sleep 0.5 echo 0 > $GPIO/value opt/wtc2.0/src/log0000644000175200017520000000436313557057144014427 0ustar bushnellbushnell••••••••• [RUBY AP] : [INFO]: set_pir_mode[0] [RUBY AP] : [INFO]: set_pir_mode [0] [RUBY AP] : [NOTICE]: [Ruby - C] cmd = 2,E,8,0,* [RUBY AP] : INFO: set_camera_temp [34] [RUBY AP] : INFO: set_camera_temp [34] [RUBY AP] : INFO: 10:08:59.133 Can't sleep : modem_state=2 , [RUBY AP] : NOTICE: [Ruby - C] cmd = 3,E,6,34,* [RUBY AP] : NOTICE: 10:08:59.178 ================== @wq_cap.enqueue_p(method(:take_picture) resume=false [RUBY AP] : NOTICE: 10:08:59.240 -------------------------take pic start!!! resume=false. 16535676 [RUBY AP] : INFO: capture_image filter= [RUBY AP] : NOTICE: [Ruby - C] cmd = 4,D,0,1,* [RUBY AP] : INFO: ????????? in gps loop .. modem is 2 and GPS 1 [RUBY AP] : INFO: 10:08:59.521 [Ruby - M0] TX : [RUBY AP] : NOTICE: [Ruby - M0] RX : return OK= packet[0]=10, packet[1]=85, packet[2]=170,packet[3]=21 [RUBY AP] : NOTICE: 10:08:59.566====-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_--_==== [RUBY AP] : INFO: 10:09:00.181 [Ruby - M0] TX : [Ruby - M0] TX : send_video/picture end [28, 0, 0] [RUBY AP] : NOTICE: [Ruby - M0] RX : [Ruby - M0] TX : send_video/picture end [28, 0, 0] return OK= packet[0]=28, packet[1]=9, packet[2]=10,packet[3]=0 [RUBY AP] : NOTICE: [Ruby - C] cmd = 5,J,1,* [RUBY AP] : WARNING: [Ruby - C] cmd = 5,J,1,* [RUBY AP] : NOTICE: [Ruby - C] cmd = 6,J,1,* [RUBY AP] : INFO: 10:09:00.319 [Ruby - M0] TX : get_day_night [RUBY AP] : NOTICE: [Ruby - M0] RX : get_day_night return OK= packet[0]=5, packet[1]=1, packet[2]=0,packet[3]=21 [RUBY AP] : ERROR: [Ruby - M0] RX : get_day_night return OK= packet[0]=5, packet[1]=1, packet[2]=0,packet[3]=21 [RUBY AP] : INFO: 10:09:00.396 [Ruby - M0] RX : get_day_night val=1 (0:night, 1:day) [RUBY AP] : NOTICE: [Ruby - C] cmd = 7,J,0,* [RUBY AP] : INFO: get day night state camera_mode=day [RUBY AP] : NOTICE: 10:09:00.538 ***** STARTING PICTURE SAVE ******** [RUBY AP] : INFO: In thumb file = /tmp/4_out_thumb_0.jpg opt/wtc2.0/src/upload_photo.rb0000644000175200017520000000703713557057144016746 0ustar bushnellbushnellrequire 'lte.rb' require 'quectel.rb' require 'http_rest_zipit.rb' require 'syslog/logger' if __FILE__ == $0 r=-1 idOK=0 imei="" iccid="" n1=n2=s1=s2=s3=0 error=-1 begin start_t =Time.now options = {} OptionParser.new do |opt| opt.on('-c', '--config config_file') { |o| options[:config_file] = o } opt.on('-p', '--photo photo_file') { |o| options[:photo] = o } opt.on('-n', '--network network_name') { |o| options[:network] = o } opt.on('-r', '--reset Y') { |o| options[:reset] = o } end.parse! if options[:config_file] == nil puts("Missing -c=") error=2 exit(error) end if options[:photo] == nil puts("Missing -c=") error=2 exit(error) end if options[:network] == nil puts("Missing -n=") error=2 exit(error) end #if the sim card or card provider has changed then reset the ppp interface if options[:reset] == 'Y' or options[:reset] =='y' m=LteModem.new(YAML.load(File.read(options[:config_file])).to_hashugar) m.resetPPPInterface() end n1=Time.now puts("Init the modem") m=LteModem.new(YAML.load(File.read(options[:config_file])).to_hashugar) val = m.enableModem # this will create the data ports # Sometimes the data ports are not created, especially after resume # The following check for return value of enableModem MUST be done # if the control program gets exit value of 5 from this script # then it must put the camera into sleep mode # IMPORTANT *** THE FOLLOWING CHECK MUST BE DONE *** if val == 5 error=val exit(error) # will need to go to sleep to try to load driver again # going to sleep - execute sleep.sh end puts("starting PPP connection") status = m.connect(options[:network]) if status !=0 puts("Error in creating connection, error code is :"+ status.to_s) error=3 exit(error) end n2=Time.now q= QuectelATCommands.new(m.getCommandPort,m.getLogName, m.getLteConfigFile) imei,iccid = q.getIMEIandICCID(0) if (imei != "") and (iccid != "") puts("Contacting server") s1=Time.now z = ZipItRestApi.new(imei,iccid,m.getAPIEndPoint,m.getSessionTokenFile,YAML.load(File.read(options[:config_file])).to_hashugar) z.register s2=Time.now #z.getCommands cdn_url,cdn_host,id = z.getThumbnailCDN(options[:photo]) #puts(cdn_url+ " " + cdn_host + " " + id.to_s) puts("Uploading photo") r=z.uploadThumbnail(options[:photo],cdn_url,cdn_host,id) s3=Time.now end rescue Exception => e puts("Exception: #{e}") puts(e.backtrace) exit(error) end finish_t = Time.now diff = finish_t - start_t puts("Time to register ppp network: " + (n2-n1).to_s + "seconds") puts("Time to register with zipit: " + (s2-s1).to_s + "seconds") puts("Time to upload 46 kb thumbnail: " + (s3-s2).to_s + "seconds") puts("Total Execution time: "+ diff.to_s+" seconds") exit r end opt/wtc2.0/src/keypad.rb0000644000175200017520000001731113557057144015522 0ustar bushnellbushnell#!/usr/bin/ruby require 'json' require 'syslog/logger' require 'optparse' require 'dem' require 'utils' require 'debug' # List of buttons to monitor #This class instantiates the buttons and listens for their press events If a #press event is received, the event is then published. # #Each button generates an event when it is pressed. The event contains #information about the button (name, etc) and the state of the button (UP or #Down). This event is fowarded by the Keypad class. Whoever listens for Keypad #events will get the button information. # #The event has the following contents: # # { :name => , :gpio => , :edge => <'falling'>|<'rising'>, :state => <'Up'>|<'Down'> } # #See BUTTONS above for details about :name, :gpio and :direction # class Keypad include EventSource include EventListener # Create a Keypad object. All defined Buttons are instantiated # def initialize(config = {}) @config = config.to_hash() @log = Syslog::Logger.new(config.log_name) @buttons=[] #puts @config['buttons'][0].to_hash() @config['buttons'].each{|button| b = Button.new(button.to_hash()) b.add_listener(self) @buttons << b } @buttons.each{|btn| Log4Ienso.log.P_INFO("Starting #{btn.get_name()}") btn.start() } end # Called whenever a button is pressed # params: # - event: the button information including up/down state def handle_event(event, data = nil) if (data[:developer] ) notify('keypad/developer_mode', event) else notify('keypad/keypress', event) end end end # This class represents a button on the keypad. The class runs a Thread # that handles button interrupts and notifies listeners when an interrupt # is detected. See keypad for its usage. class Button include EventSource @@menu_down = @@enter_down = @@right_down = false attr_reader :thread @args=nil @run=false # Create a Button object # params: # - number: The GPIO number of the button. This implementation used the sysfs GPIO interface. def initialize(args={}) @args=args @args.assert_keys(:gpio) @num = (@args[:gpio][1].ord - 'A'.ord) * 32 + @args[:gpio][2..5].to_i Syslog::Logger.new @log = Syslog::Logger.new("button_#{@num}") # Unexport the GPIO. Otherwise, interrupts will not work the second time round... # TODO: replace with Gpio class... open("/sys/class/gpio/unexport",'w'){|fd| fd.write(@num) } if File.exists?("/sys/class/gpio/gpio#{@num}") open("/sys/class/gpio/export",'w'){|fd| fd.write(@num) } # This is required. Even if default shows 'in', other pin functions (eg UART) may be in control # Setting the direction will force the GPIO function. open("/sys/class/gpio/gpio#{@num}/direction",'w'){|fd| fd.write('in') } #open("/sys/class/gpio/gpio#{@num}/active_low",'w'){|fd| # fd.write(1) #} # Needed to enable interrupt on transition. open("/sys/class/gpio/gpio#{@num}/edge",'w'){|fd| fd.write(@args[:edge]) #fd.write('both') } end def start() Thread.abort_on_exception = true #TODO: add begin/ensure to unexport GPIOs when this thread exists/gets killed. #removes the need to check before exporting them in initialize(). I.e., butter #to not leave a mess if we exits or a killed... @thread=Thread.new(@args) do |args| open("/sys/class/gpio/gpio#{@num}/value",'r'){|value| @run=true value.read() #flush what is there now... puts("going into loop gpio[#{@num}] edge[#{@args[:edge]}]") loop do rs,ws,es = IO.select(nil, nil, [value], nil) #puts("select #{@num}. es: #{es}") if es #puts("Key press detected") Log4Ienso.log.P_INFO("Keypress detected: #{@num}") r = es[0] begin #args[:proc_down].call begin Log4Ienso.log.P_INFO("Sending notification...") # Determine if the button is up or down r.rewind c = r.read(1) if c == '1' state = 'Up' elsif c == '0' state = 'Down' end # Here, args is the button information (witch # button, etc) and state is whether the button # is in the UP state or Down state. puts "button=#{@args[:name]} state=#{state}" if(@args[:name] == 'Menu') if(state == 'Down') @@menu_down = true else @@menu_down = false end elsif(@args[:name] == 'Enter') if(state == 'Down') @@enter_down = true else @@enter_down = false end elsif(@args[:name] == 'Right') if(state == 'Down') @@right_down = true else @@right_down = false end else end developer = false if(@@menu_down && @@enter_down && @@right_down) puts "====================== going to developer mode ===============" $developer_mode = true developer = true end ret = {:developer => developer } if( (state == 'Down') || (@args[:name] == 'M0 interrupt') ) notify(args.merge({:state => state}), ret ) end rescue Exception => e @log.error("Notification failed: #{e}") end rescue Exception => e @log.error("Failed to call keypress listener: #{e}") end else break if not @run end end } end end def stop() @run=false end def get_name() @args[:name] end end if $0 == __FILE__ Thread.abort_on_exception = true opt = OptionParser.new {|opts| opts.banner=<<-EOF Keypad server ============= This service detects keypad presses and notifies whoever has registered. EOF opts.on('-mURI','--mqtt-uri=URI',"The URI of the MQTT brocker. (Default: #{Options[:uri]})"){|arg| Options[:uri] = arg } } opt.parse! Keypad.new end opt/wtc2.0/src/view.rb0000644000175200017520000003257513557057144015230 0ustar bushnellbushnell require 'menu' require 'env' require 'thread' require 'lcd' require 'yaml' require 'dem' require 'version' class View include EventListener include EventSource SD_NO = 0 SD_OK = 1 SD_FULL = 2 VIEW_MODE_STATUS = 0 VIEW_MODE_SETUP = 1 @lcd = nil @desc = nil def initialize(config, env, menuL0, camera) @pwr_shut_down_flag = false @strH @strL @display_on_flag = false @env = env @config = config @camera = camera @mutex = Mutex.new @battery = 0 @rssi = 0 @sdcard = "No SD" @sdcard_stae = :removed @day_night = 'day' @disk_space = {:free=>0, :total=>0} #@num_phtos = 0 #@num_videos = 0 @num_photos_videos = 0 @view_mode = VIEW_MODE_STATUS @menu = Menu.new(env, menuL0) @cursor = nil $desc = YAML.load(File.open(@env.get_env_path + @env.get_env('desc_file'),'r')) # from yaml_string @lcd = LcdScreen.new(config.lcdctrl) @banner_cntr = 0 displayOn() # Display summary information (centered) #displayDiret("Welcome! WTC 2.0") displayDiret(" IMPULSE CAM ", 1, :left) displayDiret(get_desc("reading_sd"), 2, :center) end def init_lcd(mode = false) @lcd = nil @lcd = LcdScreen.new(@config.lcdctrl, mode) @display_on_flag = false end def pwr_shut_down? @pwr_shut_down_flag end def pwr_shut_down(flag) @pwr_shut_down_flag = flag end def refreshMenu(env,menuL0) @env = env @menu = nil @menu = Menu.new(env,menuL0) end def get_desc(msg) if((str = $desc[msg]) == nil) str = msg end str end def handle_event(event, data = nil) # Camera has finished capturing an image. if event =~ %r{keypad/keypress} if((displayOn?) && (@mutex.lock)) begin if(pwr_shut_down? ) if( data[:name] == 'Enter') displayDiret("POWERING DOWN", 1, :center) displayDiret("PLEASE WAIT", 2, :center) puts("---------------- shut down confirmed ") begin `mkdir /var/loghist` if !File.exist?('/var/loghist') suffix = `date | tr -d ' ' | tr -d ':'` puts("rotating logs ...#{suffix}") # dmesg `ls -t /var/loghist/dmesg* | sed -e '1,4d' | xargs rm -f` `dmesg > /var/loghist/dmesg.#{suffix}` `sync` #messages #`ls -t /var/loghist/messages* | sed -e '1,4d' | xargs rm -f` #system("cp /var/log/messages /var/loghist/messages.#{suffix}") #`sync` #verbose log `ls -t /var/loghist/messages_verbose* | sed -e '1,4d' | xargs rm -f` `cp /var/log/messages_verbose.txt /var/loghist/messages_verbose.#{suffix}` `sync` p = `ls /var/loghist/*` puts(p) puts("log rotation complete") rescue puts("Exception in copying logs") end @camera.power_off() notify('view/shut_down', 0) end pwr_shut_down(false) else if(@view_mode == VIEW_MODE_STATUS) if( data[:name] == 'Menu') if( ($video_recording == false) && ($final_test_flag == false) ) @view_mode = VIEW_MODE_SETUP end end else if( data[:name] == 'Menu') if( @menu.escape(data[:name]) == false) @view_mode = VIEW_MODE_STATUS end elsif( data[:name] == 'Enter') result = @menu.execute(data[:name]) dispResult(result) else @menu.key_input(data[:name]) end end end ensure @mutex.unlock end end elsif event =~ %r{comm/interrupted} elsif event =~ %r{sdcard/inserted} if(data == :begin) @sdcard_stae = :loading else @sdcard_stae = :inserted end view_update() elsif event =~ %r{sdcard/removed} if(data == :begin) @sdcard_stae = :loading else @sdcard_stae = :removed end @disk_space = {:free=>0, :total=>0} view_update() elsif event =~ %r{sdcard/num_pic} @num_photos_videos = data elsif event =~ %r{sdcard/num_vid} @num_photos_videos = data elsif event =~ %r{sdcard/num_pic_vid} @num_photos_videos = data puts "event sdcard/num_pic_vid @num_photos_videos=#{@num_photos_videos}" elsif event =~ %r{sdcard/diskSpace} @disk_space = data end end def displayOff @display_on_flag = false @view_mode = VIEW_MODE_STATUS @menu.clear() @lcd.display_off() end def displayOn? @display_on_flag end def displayOn @display_on_flag = true @lcd.display_on() @lcd.clear() @lcd.goto(1,1) @strH = "" @strL = "" end def display_turn_on_all_pixels @lcd.turn_on_all_pixels end def displayDiret(string, line=1, align=:center, cursor = nil) if(@display_on_flag == true) str = " " if(align == :center) if(string.length < 16) strStart = ((16 - string.length)/2) str1 = str[0..strStart - 1] str = (str1 + string).ljust(16," ") else str = string end elsif(align == :left) str = string.ljust(16," ") elsif(align == :right) strStart = ((16 - string.length)) str1 = str[0..strStart - 1] str = str1 + string else raise("Error") end if(line == 1) if(@strH != str) @lcd.goto(1,1) @strH = str @lcd.write_string(str) @cursor = nil end elsif(line == 2) if(@strL != str) @lcd.goto(2,1) @strL = str @lcd.write_string(str) end if(@cursor != cursor) if(cursor != nil) @lcd.set_cursor_onfoff(true) @lcd.set_cursor(cursor) else @lcd.set_cursor_onfoff(false) end @cursor = cursor end else raise("Error") end #puts "H[#{@strH}]" #puts "L[#{@strL}]" end end # one line string display on the LCD # * *Args* : # - disInfo: # - :id => want to display string # - :aligh => :center, :left, :right # - :addNum => Add Index Number in the front of string # - :cursor => display cursor, it only support line 2 # - line: want to display line (1 ~ 2) # * *Raises* : # - ArgumentError -> If failed line number def lineDisplayDesc(disInfo, line) str = get_desc(disInfo[:id]) if(disInfo[:addNum] != nil) str = "#{disInfo[:addNum]}. " + str end displayDiret(str, line, disInfo[:align], disInfo[:cursor]) end # string display on the LCD # * *Args* : # - disInfo => disInfo[0]: line 1, disInfo[1]: line 2 # - :id => want to display string # - :aligh => :center, :left, :right # - :addNum => Add Index Number in the front of string # - :cursor => display cursor # - clear: clear LCD and redisplay # * *Raises* : # - ArgumentError -> If failed line number def displayDesc(disInfo, clear = false) if( clear == true) @lcd.clear end if disInfo != nil lineDisplayDesc(disInfo[0],1) lineDisplayDesc(disInfo[1],2) end end def set_day_and_night(day = 'day') @day_night = day end def get_bat_blink if(@battery < 10) bat_str = "BAT:0#{@battery}" else bat_str = "BAT:#{@battery}" end if(@battery < 21) f1 = Time.now.to_f i1 = f1.to_i f2 = f1-i1 #puts f2 if( f2 > 0.5) bat_str = " " end end bat_str end def get_sdinfo() sd = {:align=>:left, :id =>""} if (@battery == 0) bat_str = " " else bat_str = get_bat_blink() end if(@sdcard_stae == :inserted) if(@disk_space[:free] <= @config.picman.min_free_disk + 1) sd[:id] = get_desc("sd_card_full") else #puts "get_sdinfo function and @num_photos_videos=#{@num_photos_videos}" #str1 = get_desc("cap") + ":#{@num_photos_videos}" str1 = get_desc("cap") + ":#{@num_photos_videos}" str2=str1.ljust(10) str3 = str2+bat_str sd[:id] = str3 #get_desc("cap") + ":#{@num_phtos} #{@num_videos} BAT:#{@battery}" end elsif(@sdcard_stae == :loading) sd[:id] = get_desc("reading_sd") sd[:align] = :left else sd[:id] = get_desc("NO SD ")+bat_str end sd end def dispResult(result = 'success') lineDisplayDesc({:id => result, :align=>:center}, 2) sleep(1) #wait for notice end def set_battery(level) @battery = level end def get_battery() @battery end def set_rssi(level) @rssi = level end def view_update if((displayOn?) && (@mutex.try_lock)) begin if (@pwr_shut_down_flag == false) if(@view_mode == VIEW_MODE_STATUS) if ($video_recording == true) hLine1 = {:id=>"#{get_desc('recording')} ", :align=>:left} hLine2 = {:id=>"#{get_desc('wait')} ", :align=>:left} elsif ($final_test_flag) if(!$imei_iccid_valid) hLine1 = {:id=>"GETTING IMEI-SIM", :align=>:left} f1 = Time.now.to_f ; i1 = f1.to_i ; f2 = f1-i1 if $final_test_start_time != nil st_time1 = Time.now - $final_test_start_time else st_time1 = 0 end st_time = st_time1.to_i @banner_cntr +=1 case @banner_cntr when 1 str = " Waiting . " when 2 str = " Waiting .. " when 3 str = " Waiting ... " when 4 str = " Waiting .... " when 5 str = " Waiting ..... " else @banner_cntr =0 str = " Waiting ......" end str1 = " Waiting = #{st_time}" hLine2 = {:id=>str1, :align=>:left} else str1 = " " hLine2 = {:id=>str1, :align=>:left} str = $imei[-5..-1] + " " + $iccid[-7..-1] puts "imei, iccid = #{str}" #@version = Version.new() if $firmware_ver == nil version = "" else version = $firmware_ver #@version.get_version() end str2 = version.rjust(7) str3 = $version_m0.rjust(7) str4 = str2[-7..-1] +" "+str3[-7..-1] puts "version=#{str2}" hLine1 = {:id=>str, :align=>:left} hLine2 = {:id=>str4, :align=>:left} end else hLine1 = {:id=>"#{get_desc('mode')}:#{get_desc(@env.get_env_value('capture_mode'))} #{get_desc('sig')}:#{@rssi}", :align=>:left} hLine2 = get_sdinfo() end desc = [hLine1, hLine2] else desc = @menu.get_view(); end displayDesc(desc) end ensure @mutex.unlock end end end end opt/wtc2.0/src/nmea.rb0000644000175200017520000000743513557057144015173 0ustar bushnellbushnell#!/usr/bin/env ruby # file: nmea_parser.rb require 'time' require 'date' require 'readline' class Coordinates def initialize( string ) a = string.split('.') langth = a[0].length @degree = "" @minute = "" @second = "" for i in 0..(langth - 3) @degree[i] = a[0][i] end i = i+1 j = i for i in i..(langth - 1) @minute[i - j] = a[0][i] end langth = a[1].length @second[0] = '0' @second[1] = '.' @second[2] = a[1][0] @second[3] = a[1][1] @second[4] = a[1][2] @second[5] = a[1][3] end def degree @degree.to_i end def minute @minute.to_i end def second @second.to_f * 60 end end class Nmea def initialize(tty) @tty = tty @gps = File.new(@tty, File::RDWR) @date = "010101" @time = "000000" @ns = 'N' @ew = 'E' makeDateTime() @lat = Coordinates.new("0000.0000") @lon = Coordinates.new("00000.0000") @th = Thread.new(){ while true do begin raw_nvme = @gps.readline() if( parse(raw_nvme) != nil) #puts DateTime() end rescue => exception puts exception puts "Error Restart NMEA Thread" @gps.close @gps = File.new(@tty, File::RDWR) end end } end def parse(raw_line) msgcode = raw_line[/^\$GP(\w+)/] return unless msgcode a = raw_line.split(',') case msgcode when /RMC/ _, @time, _, lat, @ns, lon, @ew, @speed, @course, @date, @variation = a #puts @time + " " + @date makeDateTime() @lat = Coordinates.new(lat) @lon = Coordinates.new(lon) else msgcode = nil end msgcode end def dateTime @dateTime end def lat @lat end def ns @ns end def lon @lon end def ew @ew end def get_env_latitude #43°51'15.2\"" "#{ns} %02d°"%lat.degree + "%02d'"%lat.minute + "%02d."%lat.second.to_i + "%1d\""%(lat.second * 10).to_i end def get_env_longitude "#{ew} %03d°"%lon.degree + "%02d'"%lon.minute + "%02d."%lon.second.to_i + "%1d\""%(lon.second * 10).to_i end private def decimalize(raw_x, raw_nesw) nesw = {n: :+, e: :+, s: :-, w: :-} x = 0.method(nesw[raw_nesw.downcase.to_sym]).call(raw_x.to_f) degrees = (x / 100).to_i minutes = x - (degrees * 100.0) (degrees + (minutes / 60)).round(8) end def makeDateTime() #"2018:08:01 12:12:12" @dateTime = "" @dateTime[0] = '2' @dateTime[1] = '0' @dateTime[2] = @date[4] @dateTime[3] = @date[5] @dateTime[4] = ':' @dateTime[5] = @date[2] @dateTime[6] = @date[3] @dateTime[7] = ':' @dateTime[8] = @date[0] @dateTime[9] = @date[1] @dateTime[10] = ' ' @dateTime[11] = @time[0] @dateTime[12] = @time[1] @dateTime[13] = ':' @dateTime[14] = @time[2] @dateTime[15] = @time[3] @dateTime[16] = ':' @dateTime[17] = @time[4] @dateTime[18] = @time[5] @dateTime end end # Test code... if $0 == __FILE__ puts "TEST NMEA" np = Nmea.new( '/dev/ttyS1') while true do end #s = '$GPGGA,045612.00,5554.95457,N,00306.82246,W,1,08,1.22,96.7,M,49.8,M,,*76' #s = '$GPRMC,120543.000,V,0000.0000,N,00000.0000,E,000.0,000.0,280606,,,N*7D' #np = NMEAParser.new(s) #np.to_h ##puts np.time #puts np.latitude #puts np.longitude endopt/wtc2.0/src/modemtime.sh0000755000175200017520000000021413557057144016231 0ustar bushnellbushnell #set time export TZ=0 if [ -e /dev/ttyUSB3 ] then echo "at+ctzu=3" > /dev/ttyUSB3 sleep 0.3 echo "at+ctzr=2" > /dev/ttyUSB3 fiopt/wtc2.0/src/debug.rb0000644000175200017520000001605313557057144015335 0ustar bushnellbushnell# # Copyright (c) IENSO Inc 2018 # # Filename : debug.rb # Author : Jack Kim (jack.kim@ienso.com) # require 'rbconfig' require 'utils' require 'constants' class Log4IensoE def self.log if @logger.nil? @logger = Debug.new end @logger end class Debug WHOAMI = "[RUBY AP] : " def self.log if @logger.nil? @logger = Debug.new end @logger end private def initialize (err = true, warn = true, notice = true, info = true) @config = {:err => err, :warn => warn, :notice => notice, :info => info} @log_sinks = [] if which('logger') @syslog = IO.popen("logger -t L4I", "w") add_log_sink(@syslog) end end # \brief Add a new log sink. A sink is the destination of a log message. For example a file or a socket # kkjjk def add_log_sink(sink) raise Exception.new("Sink must respond to the :puts method") if not sink.respond_to?(:puts) @log_sinks << {:sink => sink, :enabled => true} if not sink.nil? end # \brief Gets a formated string of the calling function def _get_caller if caller.size > 2 call = caller[2].split(/:/) # caller[0] is the P_* functions below. We want the next in the stack that called teh P_* methods... "#{File.basename(call[0])}:#{call[1]}" else ":" end end def _output_to_sinks(data) begin @log_sinks.each{|sink| sink[:sink].puts("#{data}\n") if sink[:enabled] } rescue Exception => e # Can we write to syslog? if RbConfig::CONFIG["host_os"] =~ /linux/ and which('logger') `logger "#{WHOAMI}: Debug error while attempting to write to sink: #{e}"` else # last resort puts("#{WHOAMI}: Debug error while attempting to write to sink: #{e}") end end end def P_ERR (msg = nil) if @config[:err] == true && msg != nil _output_to_sinks("ERROR:#{_get_caller}:#{msg}") end end def P_WARN (msg = nil) if @config[:warn] == true && msg != nil _output_to_sinks("WARNING:#{_get_caller}:#{msg}") end end def P_NOTICE (msg = nil) if @config[:notice] == true && msg != nil _output_to_sinks("NOTICE:#{_get_caller}:#{msg}") end end def P_INFO (msg = nil) if @config[:info] == true && msg != nil _output_to_sinks("INFO:#{_get_caller}:#{msg}") end end def P_CLEAN (msg = nil) if @config[:info] == true && msg != nil _output_to_sinks("CLEAN:#{_get_caller}:#{msg}") end end def P_BLUE (msg = nil) if @config[:info] == true && msg != nil _output_to_sinks("BLUE:#{_get_caller}:#{msg}") end end def P_CYAN (msg = nil) if @config[:info] == true && msg != nil _output_to_sinks("CYAN:#{_get_caller}:#{msg}") end end def P_MAGENTA (msg = nil) if @config[:info] == true && msg != nil _output_to_sinks("MAGENTA:#{_get_caller}:#{msg}") end end def P_YELLOW (msg = nil) if @config[:info] == true && msg != nil _output_to_sinks("YELLOW:#{_get_caller}:#{msg}") end end end # end of class Debug private_constant :Debug end class Log4Ienso def self.log if @logger.nil? @logger = Debug.new end @logger end class Debug ANSI_C_RESET = "\033[0m" ANSI_C_RED = "\033[1;31m" ANSI_C_GREEN = "\033[1;32m" ANSI_C_YELLOW = "\033[1;33m" ANSI_C_BLUE = "\033[1;34m" ANSI_C_MAGENTA = "\033[1;35m" ANSI_C_CYAN = "\033[1;36m" WHOAMI = "[RUBY AP] : " VERBOSE_FILE_LOGGING = 0 # 1 will redirect output to file, not for production use LOG_FILE = '/var/log/messages_verbose.txt' LOG_FILE_PREVIOUS = '/var/log/messages_verbose.txt.1' def initialize (err = true, warn = true, notice = true, info = true) @config = {:err => err, :warn => warn, :notice => notice, :info => info} if VERBOSE_FILE_LOGGING == 1 old_stdout = $stdout fo = File.new(LOG_FILE, 'a') $stdout = fo ObjectSpace.define_finalizer(self, proc { $stdout = old_stdout }) end end # Note: this method is not thread safe, some logging calls will fail at time of log rollover def trunacteLogSizeinProudctionUse begin fs=0 fs = File.size(Constant::LOG_FILE) if File.exists?(Constant::LOG_FILE) if fs.to_i > Constant::MAX_VERBOSE_LOG_FILE #log size is greater than x MB `rm #{Constant::LOG_FILE_PREVIOUS}` if File.exists?(Constant::LOG_FILE_PREVIOUS) `mv #{Constant::LOG_FILE} #{Constant::LOG_FILE_PREVIOUS} ` @old_stdout = $stdout fo = File.new(Constant::LOG_FILE, 'a') $stdout = fo `sync` end rescue puts("rescue in log rollover") end end def P_ERR (msg = nil) if @config[:err] == true && msg != nil print (ANSI_C_RED + WHOAMI) puts (msg) print (ANSI_C_RESET) end end def P_WARN (msg = nil) trunacteLogSizeinProudctionUse if @config[:warn] == true && msg != nil print (ANSI_C_YELLOW + WHOAMI) puts (msg) print (ANSI_C_RESET) end end def P_NOTICE (msg = nil) if @config[:notice] == true && msg != nil print (ANSI_C_CYAN + WHOAMI) puts (msg) print (ANSI_C_RESET) end end def P_INFO (msg = nil) trunacteLogSizeinProudctionUse if @config[:info] == true && msg != nil print (WHOAMI) puts (msg) end end def P_CLEAN (msg = nil) if @config[:info] == true && msg != nil print (ANSI_C_GREEN) puts msg print (ANSI_C_RESET) end end def P_BLUE (msg = nil) if @config[:info] == true && msg != nil print (ANSI_C_BLUE) puts msg print (ANSI_C_RESET) end end def P_CYAN (msg = nil) if @config[:info] == true && msg != nil print (ANSI_C_CYAN) print msg print (ANSI_C_RESET) end end def P_MAGENTA (msg = nil) if @config[:info] == true && msg != nil print (ANSI_C_MAGENTA) puts msg print (ANSI_C_RESET) end end def P_YELLOW (msg = nil) if @config[:info] == true && msg != nil print (ANSI_C_YELLOW) puts msg print (ANSI_C_RESET) end end end # end of class Debug private_constant :Debug end if $0 == __FILE__ Log4Ienso.log.P_INFO("test Log4Ienso") File.mkfifo("/tmp/test_fifo") if not File.exists?("/tmp/test_fifo") fifo = File.new("/tmp/test_fifo", 'r+') Log4Ienso.log.add_log_sink(fifo) Log4Ienso.log.P_INFO("test2 Log4Ienso") end opt/wtc2.0/src/utils.rb0000644000175200017520000000527413557057144015412 0ustar bushnellbushnell # -------------------------- id number --------------------------- SYSINFO_START = 0 SYSINFO_MAGIC = SYSINFO_START SYSINFO_HEADER_VER = 1 SYSINFO_ACTIVE_SLOT =2 SYSINFO_UUID = 3 SYSINFO_MANUFACTURER = 4 SYSINFO_PRODUCT = 5 SYSINFO_MODEL = 6 SYSINFO_HARDWARE_ID = 7 SYSINFO_SERIAL = 8 SYSINFO_ALIAS = 9 SYSINFO_SLOT_START =10 SYSINFO_SUCCESS = SYSINFO_SLOT_START SYSINFO_FAILCNT = 11 SYSINFO_MODULE_START =12 SYSINFO_MODULE_VER = SYSINFO_MODULE_START SYSINFO_MODULE_DATE = 13 SYSINFO_MODULE_TIME = 14 SYSINFO_MODULE_END = 15 SYSINFO_SLOT_END = SYSINFO_MODULE_END SYSINFO_CRC = SYSINFO_SLOT_END SYSINFO_END = 16 # ------------------------ module number ------------------------- MODULE_START = 0 MODULE_FACTORY = MODULE_START MODULE_BOOT0 = 1 MODULE_UBOOT = 2 MODULE_MBR = 3 MODULE_RESOURCE = 4 MODULE_ENV = 5 MODULE_KERNEL = 6 MODULE_VFAT = 7 MODULE_ROOTFS = 8 MODULE_APP = 9 MODULE_M0 = 10 MODULE_MAX = 11 class Hashugar def initialize(hash) @table = {} @table_with_original_keys = {} hash.each_pair do |key, value| hashugar = value.to_hashugar @table_with_original_keys[key] = hashugar @table[stringify(key)] = hashugar end end def method_missing(method, *args, &block) method = method.to_s if method.chomp!('=') @table[method] = args.first else @table[method] end end def [](key) @table[stringify(key)] end def []=(key, value) @table[stringify(key)] = value end def respond_to?(key, include_all=false) super(key) || @table.has_key?(stringify(key)) end def each(&block) @table_with_original_keys.each(&block) end def to_hash hash = @table_with_original_keys.to_hash hash.each do |key, value| hash[key] = value.to_hash if value.is_a?(Hashugar) end end def empty? @table.empty? end private def stringify(key) key.is_a?(Symbol) ? key.to_s : key end end class Hash def to_hashugar Hashugar.new(self) end end class Hash def assert_keys(*keys) keys.each{|key| raise "#{key} not present" if not has_key?(key)} end end class Array def to_hashugar map(&:to_hashugar) end end class Object def to_hashugar self end end def which(cmd) ENV['PATH'].split(/:/).each{|p| return true if File.exists?(p + File::SEPARATOR + cmd) } return false end # Unit test code if $0 == __FILE__ a={:a => 'a', :b => 'b'} a.assert_keys(:a) a.assert_keys(:b) a.assert_keys(:a, :b) a.assert_keys(:a, :b, :c) end opt/wtc2.0/src/control.rb0000644000175200017520000050473313557057144015736 0ustar bushnellbushnell#!/usr/bin/ruby # The following is an instruction to rdoc. It specifies the main page for the documentation. # This directive must appear in a .rb file. We placed it here because this is the main # control of the application. # :main: README.txt $LOAD_PATH.push File.expand_path("..", __FILE__) $video_recording = false $final_test_flag = false $final_test_start_time = nil $final_test_finished_flag = false $imei_iccid_valid = false $imei= nil #can be from imei.txt or actual hardware $iccid= nil #can be from imei.txt or actual hardware $hwimei = nil # from hardware $hwiccid = nil # from hardaware $imsi= nil $version_m0 = "" $menu_values_changed = false $lastupdatetime = "1970-01-01T12:00:00" $developer_mode = false $networkname ="" $qtel_firmware = nil $testserver = nil $gps_wakeup_flag = false $firmware_ver = nil #$power_reset_cntr = 0 $ip_failed_cntr = 0 $camera_timezone="+0" $wifi_timeout=600 #time after which the wifi will shut down $tracking_enabled_oncamera = false $trigger="" $nonetworkregistercount=0 $serverCMDSRcvd = false #track if in daily checkin the server cmds were received $pir_confirmation_flag = false $dailyAlertTimeUpdate = false $send_end_pic_flag = false $rssi = 0 $model='' $cammoduleresecount = 0 #zero sized thumbnails need a system reboot $is_ffmeg_started = false $verizonfimwarebugfix = false $usbErrorCount = 0 #track usb modem connection errors and reboot if more then 3 $dstrebootflag = 0 #manage reboot due to DST $timechangedcounter = 0 # counter to manage changing system time during runtime (used in setLocalTime (Quectel)) $atERRORs = 0 $atERRORcmd = "" $tzERRORs = 0 $ftpERRORs = 0 $gpsTTFFsum = 0 $gpsTTFFcnt = 0 $gpsFixAttemps = 0 require 'yaml' require 'json' require 'optparse' require 'syslog/logger' require 'utils' require 'menu' require 'view' require 'timer' require 'comm' require 'env' require 'work_que' #require 'nmea' require 'camera' require 'keypad' require 'picture_manager' require "monitor" require "connection_manager" require 'version' require 'gpio' require 'mqtt' require 'debug' require 'sysinfo' require 'constants' #require 'objspace' #require 'allocation_stats' Thread.abort_on_exception = true # This is the central control for the WTC2.0 application. Control is responsible for all # operations and performs them with the help of other classes and processes. class Control include EventListener @log = nil # params: # - config: This is the contents of the application configuration file. See config.yaml for details. def initialize(config={}) #system(%Q(/opt/wtc2.0/src/sleep.sh)) #sleep(1) #system(%Q(modprobe -v 8723bs)) #`dmesg -n 8` #`dmesg &` @time_updated = false @final_test_pir_cntr = 0 @old_stdout = $stdout @store_key_pressed_flag = false @config = config @keypad = nil @log = Syslog::Logger.new(@config.control.log_name) @awake_send_vid_pic_end_flag = true @set_field_scan_flag=true @take_picture_in_process=false @remaining_pictures_no=0 @hbit_timeout = 60 # Network Variables @modem=nil @quectelcmds=nil @thread_photo = nil @thread_modem = nil @thread_gps = nil @rssi = 0 @networkstate=0 #0 not available, 1 available @final_test_start_time = nil @modem_state = Constant::MODEM_OFF @modem_sleep_run = true @upload_photo_count=0 @upload_photo_count_copy=0 @update_view_flag = true @triedconnecting=0 @sdcard_status = false @disk_space = {:free=>0, :total=>0} @version = Version.new() @modemstarttime = nil @photocell_change_req_count = 0 @hotspot = 0 @hotspotactivated = 0 @sleep_con_check=0 @startmode = Constant::COLD_BOOT @streaming = Constant::STREAMING_OFF @sleep_count = 0 @isMenuDirty = false @wakeupcounter = 0 #count the number of wakeups in this session @gpstrycounter = 0 #manage gps wakeup time @read_bat_counter = 0 @gps_state = Constant::GPS_SWITCHED_OFF @image_to_network_try = 0 @latitude = @longitude = @satellite = @gps_errcode =0 @cut_off_time = Constant::NO_GPS_DATA_TIME @cut_off_time_counter = 0 # counts how many times camera was stuck @location_available = false # Developer note: setting this to true will stop execution of GPS code @accessgpstate = Mutex.new @dailycheckin = true # TO DO set to false once daily timer is enabled @storageused = @storagesize = 0 @gpstime= nil @trackingstate = 0 @firmwareRemoteRequest = @dailyMode = 0 # do not apply the cut off timer in SendPhoto mode when in these modes @firmwareota_thread = nil @continueUpload = 0 @menu_test_image = 0 # Load Environment setting file and International Language descript @env = Env.new(config.def_env) @mutex_env = Mutex.new @photoThreadCount=0 @gpsxtraupdate = false setDefaultTime @camera = CameraControl.new(@config.camctrl, get_env) @starttype = Constant::COLD_BOOT @view = View.new(@config, get_env, initial_menu(), @camera) @turn_on_display_flag = false updatePhotoUploadCount @elapsedTime = 0 @updateServer = 0 @otaupload = false @overridePhotoUploadBlock = false @dailyupdatetimedelta = 0 @lastotatime = 0 @photoThreadExited = false @longPhotoUploadSession = false @pmic_not_fake_pir = false sysinfo = SysInfo.new() m = sysinfo.getSysInfo(Constant::MODEL_NAME) m=m.chomp.strip $model = "primos" if m == 'BUSHNELL PRIMOS' $model = "impulse" if m == 'BUSHNELL IMPULSE' @wq_cap = WorkQueue.new 1, Constant::MAX_CAP_QUE @wq_send = WorkQueue.new Constant::MAX_SERVER_SNED_QUE, Constant::MAX_SERVER_SNED_QUE @mqtt_th = Thread.new{ getMqttMessages } @active_slot = @camera.get_active_slot() @active_slot = @active_slot.to_i if @active_slot != nil $firmware_ver = @camera.get_sysinfo(SYSINFO_MODULE_VER, @active_slot, MODULE_APP) @delay_default = @mutex_env.synchronize{@env.get_env_value('imaage_interval')} @comm = Comm.new(@config.m0ctrl, [[0x02,@mutex_env.synchronize{@env.get_env_value('Set_photocell')}],[0x06, @delay_default], [0x0c,@mutex_env.synchronize{@env.get_env_value('capture_mode')}, @mutex_env.synchronize{@env.get_env_value('movie_length')}] ]) $version_m0 = @comm.get_mo_revision() Log4Ienso.log.P_NOTICE( "###########################################") Log4Ienso.log.P_NOTICE( "# Model: #{m} / #{$model}") Log4Ienso.log.P_NOTICE( "# Slot: #{@active_slot}") Log4Ienso.log.P_NOTICE( "# App: #{$firmware_ver}") Log4Ienso.log.P_NOTICE( "# M0: #{$version_m0}") Log4Ienso.log.P_NOTICE( "###########################################") # Listent to keypad events @keypad = Keypad.new(@config.keypadctrl) @picman = PictureManager.new(@config.picman) @irled_gpio = Gpio.new('PH7') @irled_gpio.direction = 'out' @irled_gpio.clear sleep(0.25) @irled_gpio.set sleep(0.25) @irled_gpio.clear sleep(0.25) @irled_gpio.set sleep(0.25) @irled_gpio.clear @t1_pulse = 0 @t2_pulse = 0 @t3_pulse = 0 set_file_logging() @thread_modem = Thread.new { startModemandNetwork(@mutex_env.synchronize{@env.get_env_value('Select_Network')}, @starttype) @starttype = Constant::RESUME_WAKEUP if @starttype == Constant::COLD_BOOT } if @env.get_env('report_interval') == 'daily' || @env.get_env('report_interval') == 'never' || @env.get_env('wirless_on/off') == 'off' #@thread_photo = Thread.new { sendPhotos(Constant::GET_SERVER_CMDS_ONLY) } @modeSDCardRead = Constant::DONOT_READ_SD_CARD Log4Ienso.log.P_NOTICE("Network communication is off due to SEND or WIRELESS setting") else @modeSDCardRead = Constant::READ_SD_CARD @thread_photo = Thread.new { sendPhotos(Constant::UPLOAD_PHOTOS_AND_SERVER_CMDS) } end sleep (0.3) Log4Ienso.log.P_NOTICE("env value is #{@mutex_env.synchronize{@env.get_env('switch_on/off_gps')}}") if @connmanager != nil && @location_available == false @thread_gps = Thread.new { getGPSLocation } end @fake_pir_flag = false @mutex_sleep = Mutex.new @thread_save_pic = nil @timer_lcd_off = Timer.new(@mutex_env.synchronize{@env.get_env_value('lcd_off_time')}) @timer_sleep_guard = Timer.new(Constant::SLEEP_GUARD_TIME) @timer_picture_burst = Timer.new(Constant::PICTURE_BURST_TIME) @timer_imagetest = Timer.new('never', method(:check_send_image_to_network), false) @timer_banner = Timer.new('never', method(:banner), false) @timer_verizonreset = Timer.new('never', method(:resetVerizonAPN),false) @banner_cntr = 0 @timer_banner_flag = false @picman.add_listener(@view) @picman.add_listener(self) @timer_check_wakeup_reason = Timer.new('never', method(:check_wakeup_reason_timer), false) @keypad.add_listener(self) @keypad.add_listener(@view) @view.add_listener(self) @comm.add_listener(self) @camera.add_listener(self) $ip_failed_cntr = 0 #@debug_pin = Gpio.new(123) #@debug_pin.direction='out' #@debug_pin.clear @keypressed = nil camera_get_set_day_night() send_camera_name() @comm.interrupt_mask(false) @picman.start() @timer_heart_bit = Timer.new('never', method(:heart_bit), false) @heart_bit_flag = false @heart_bit_timer_started_flag = false enable_heart_bit() if !$final_test_flag updatePhotoUploadCount initial_M0() @m0_reset_counter1, @m0_reset_counter2 = @comm.get_reset_counter Log4Ienso.log.P_NOTICE("===NOTE: A83 was reset by M0 total=#{@m0_reset_counter1}, (heat beat=#{@m0_reset_counter2}) times by now ===") @power_reset_cntr = @env.get_env_value('reset_cntr').to_i Log4Ienso.log.P_CLEAN("====@power_reset_cntr=#{@power_reset_cntr } ===\n") @fake_pmic_pir_cntr = 0 #@env.get_env_value('fake_pmic_pir_cntr').to_i Log4Ienso.log.P_CLEAN("====@fake_pmic_pir_cntr=#{@fake_pmic_pir_cntr } ===\n") @fake_pir_cntr = 0 #@env.get_env_value('fake_pir_cntr').to_i Log4Ienso.log.P_CLEAN("====@fake_pir_cntr=#{@fake_pir_cntr } ===\n") @nfake_pir_cntr = 0 #@env.get_env_value('nfake_pir_cntr').to_i Log4Ienso.log.P_CLEAN("====@nfake_pir_cntr=#{@nfake_pir_cntr } ===\n") @reboot_flag = false #reset M0 state - the ground truth is the A83 env value @dailyCheckinStatus = @env.get_env('dailycheckin') Log4Ienso.log.P_NOTICE("Daily checkin status is #{@dailyCheckinStatus}") if @dailyCheckinStatus == Constant::FAILED_TWICE @env.save_env_val('dailycheckin',0 ) #reset end if ( @env.get_env('tracking') == 'on') Log4Ienso.log.P_NOTICE("=== THEFT MODE IS ON ===") if @env.get_env('gps_tracking') == 'on' Log4Ienso.log.P_NOTICE("=== THEFT MODE ACTIVE MOVEMENT ON ===") @comm.check_theft_mode_on_reboot @trackingstate = 1 $tracking_enabled_oncamera = true else @env.save_env_val('gps_tracking', "off") @comm.enable_theft_mode @trackingstate = 0 $tracking_enabled_oncamera = true end else Log4Ienso.log.P_NOTICE("=== THEFT MODE IS OFF ===") @comm.disable_theft_mode @env.save_env_val('gps_tracking', "off") @trackingstate = 0 $tracking_enabled_oncamera = false end # the following conditions only happens if the camera resets in the middle of the daily alert # when the state is daily or never if @env.get_env('activecommstate') == Constant::SEND_PIC_DAILY && @env.get_env('gps_tracking') == 'off' @longPhotoUploadSession = true $gps_wakeup_flag = true Log4Ienso.log.P_NOTICE("Active DAILY MODE FOUND - daily alert event will continue") end if @env.get_env('activecommstate') == Constant::SEND_PIC_NEVER && @env.get_env('gps_tracking') == 'off' @dailyCheckinMode = true $gps_wakeup_flag = true $serverCMDSRcvd = true Log4Ienso.log.P_NOTICE("Active NEVER MODE FOUND - daily alert event will continue") end Log4Ienso.log.P_NOTICE("===GPS starting state is #{@gps_state } ===") @picuploadcontrol = Mutex.new #ObjectSpace.trace_object_allocations_start #stats = AllocationStats.trace do #puts "allocationstats test" #end end def getMqttMessages begin MQTT::Client.connect('localhost') do |c| # If you pass a block to the get method, then it will loop c.get('wtc/webserver') do |topic,message| Log4Ienso.log.P_NOTICE("#{topic}: #{message}") if topic == 'wtc/webserver' refreshMenu if message == 'envupdated' startStreaming if message =='startstreaming' endStreaming if message == 'endstreaming' disableHotspot if message == 'endhotspot' updateCameraName if message=="camera_name" updateShutterSpeed if message=="shutter_speed" updateImageResolution if message=="image_resoluition" updateMovieResolution if message=="movie_resoluition" updateMovieLength if message=="movie_length" updatePirDelay if message=="imaage_interval" updateledIntensity if message=="led_power" updateTimeStamp if message=="show_timestamp" updatePirMode if message=="pir_mode" updateTimeOfOperation if message=="tos" updateFieldScan if message=="fieldscan" updateTracking if message=="tracking" updateCaptureMode if message=="capture_mode" end sleep(0.1) Thread.pass end end rescue Exception => e Log4Ienso.log.P_ERR("MQTT error " + e.backtrace.to_s) disableHotspot Thread.exit end end def is_numeric?(obj) obj.to_s.match(/\A[+-]?\d+?(\.\d+)?\Z/) == nil ? false : true end def compareFirmwareVersions(remoteVersion, localVersion) remoteVersion = remoteVersion.strip.chomp localVersion = localVersion.strip.chomp rv = remoteVersion.split('.') rvval = rv[0].to_i*100000000 + rv[1].to_i*10000 + rv[2].to_i lv = localVersion.split('.') lvval = lv[0].to_i*100000000 + lv[1].to_i*10000 + lv[2].to_i if lvval >= rvval Log4Ienso.log.P_NOTICE("NOT Upgrading: - local version is greater/equal to remote") return 1 else Log4Ienso.log.P_NOTICE("Upgrading: local version is less than remote") return 0 end end def downloadFirmwareOTA(mode = 0) updatingM0 = 0 Log4Ienso.log.P_MAGENTA("Starting OTA download process\n" ) @otaupload = true `rm /opt/*.enc` readytoboot = false downloadSlot = 1 if @active_slot == 1 downloadSlot = 0 if @active_slot == 0 if @connmanager != nil upgradecount=0 Log4Ienso.log.P_NOTICE("OTA getting manifest" ) manifest = @connmanager.getFirmWareManifest begin json_resp = JSON.parse(manifest) Log4Ienso.log.P_NOTICE("XXXXXXXXXXXXXXX") Log4Ienso.log.P_NOTICE("remote version is " + json_resp["Version"]) serverVersion = json_resp["Version"] if mode == Constant::ONLY_UPGRADE_FIRMWARE result = compareFirmwareVersions(serverVersion, $firmware_ver ) if result == 1 Log4Ienso.log.P_NOTICE("Cannot downgrade over daily alert") @dailyMode = 0 @connmanager.setIsOTASessionActive(false) @cut_off_time = 10 @env.save_env_val('dailycheckin',0 ) #reset daily checkin to noraml state @otaupload = false return end end #Log4Ienso.log.P_NOTICE($firmware_ver) json_resp["Components"].each do |comp| puts comp["Version"] comp_ver = @camera.get_sysinfo(SYSINFO_MODULE_VER, downloadSlot, comp["Component"].to_i) otaversion = comp["Version"] otaversion = otaversion.to_i.to_s(16) localversion = getintvalues(comp_ver) otaversion = fixLength(localversion,otaversion) Log4Ienso.log.P_MAGENTA("ota version is #{otaversion} and local is #{localversion}\n") if otaversion.to_s.strip != localversion.to_s.strip upgradecount +=1 end end rescue Exception=>e Log4Ienso.log.P_ERR("exception in parsing firmware manifest " + e.to_s ) @dailyMode = 0 @connmanager.setIsOTASessionActive(false) end Log4Ienso.log.P_CLEAN("**************************************\n" ) Log4Ienso.log.P_MAGENTA("Module upgrade count is #{upgradecount}\n" ) Log4Ienso.log.P_CLEAN("***************************************\n" ) begin json_resp = JSON.parse(manifest) json_resp["Components"].each do |comp| comp_ver = @camera.get_sysinfo(SYSINFO_MODULE_VER, downloadSlot, comp["Component"].to_i) otaversion = comp["Version"] otaversion = otaversion.to_i.to_s(16) localversion = getintvalues(comp_ver) otaversion = fixLength(localversion,otaversion) Log4Ienso.log.P_MAGENTA("ota version is #{otaversion} and local is #{localversion}\n") if otaversion != localversion Log4Ienso.log.P_CLEAN("downloading module no #{upgradecount} because ota is #{otaversion} and local #{localversion}\n" ) url = comp["FileURL"].strip.chomp url = url[8..-1] `wget -P /opt #{url} -T #{Constant::OTA_UPDATE_TIME} ` if comp["Component"].to_i == MODULE_M0 Log4Ienso.log.P_MAGENTA("Upgrading M0 starting UART shutdown from A83\n") #enter_special_func() updatingM0 = 1 disable_heart_bit @comm.set_upgrade_flag() if @comm != nil end fp = "/opt/"+ File.basename(url) Log4Ienso.log.P_BLUE("********* #{upgradecount}\n" ) @camera.request_upgrade(fp,comp["Key"],upgradecount) #if upgradecount == 1 # Log4Ienso.log.P_INFO("_____sleeping____" ) # sleep(10) #end upgradecount-=1 Log4Ienso.log.P_BLUE("********* #{upgradecount}\n" ) readytoboot = true if upgradecount == 0 end end rescue Exception=>e Log4Ienso.log.P_ERR("exception in parsing firmware manifest " + e.to_s ) ensure if readytoboot == false @dailyMode = 0 #@comm.set_upgrade_flag(false) if @comm != nil @connmanager.setIsOTASessionActive(false) @otaupload = false end if updatingM0 == 1 enable_heart_bit Log4Ienso.log.P_ERR("---- REBOOTING because M0 accessed---- ") sleep(4) system('reboot') end end end Log4Ienso.log.P_CLEAN("||||| Finished Firmware Upgrade |||||\n") @otaupload = false @env.save_env_val('dailycheckin',0 ) #reset daily checkin to noraml state @cut_off_time = 10 #reduce time to sleep if no firmware upgrade if readytoboot == true Log4Ienso.log.P_NOTICE("---- REBOOTING ---- ") sleep(4) system('reboot') end end def getintvalues(x) #y=x.gsub!(/[.]/, '') n=0 y=x.split(".") r="" while n< y.length do puts(y[n]) if y[n].to_i.to_s(16).length == 1 y[n] = "0" + y[n].to_i.to_s(16) else y[n] = y[n].to_i.to_s(16) end r = r + y[n] n+=1 end return r end def fixLength(local,ota) ota=ota.to_s pad="" l1 = local.length l2 = ota.length diff = l1 -l2 puts("diff is #{diff}") while diff > 0 pad = pad + "0" diff-=1 end ota = pad + ota.to_s return ota end def getGPSLocation return if $model=="primos" Log4Ienso.log.P_CLEAN("getGPSLocation: ------------ Starting GPS loop with modem state ------------------- " + @modem_state.to_s) startTS = Time.now $gpsFixAttemps += 1 rval=lat=lng=count=delay=0 loop do # Aiding data need valid timezone information so we need to wait until after the time is set if (@time_updated == false) && (delay * Constant::GPS_CHECK_TIME < Constant::GPS_WAIT_TIME) # if $camera_timezone.to_i != 0 # Log4Ienso.log.P_WARN("getGPSLocation: GPS_WAIT_TIME already set EXIT") # break # end sleep Constant::GPS_CHECK_TIME Thread.pass next else Log4Ienso.log.P_WARN("getGPSLocation: GPS_WAIT_TIME EXIT") break end end loop do count+=1 if $final_test_flag Log4Ienso.log.P_ERR("getGPSLocation: exit gps loop if final test") break end if (@modem_state >= Constant::MODEM_PORTS_AVAILABLE && @gps_state > Constant::GPS_ABORTED && @gps_state < Constant::GPS_FIXED ) Log4Ienso.log.P_INFO("getGPSLocation: modem is #{@modem_state} and GPS #{@gps_state} : #{@gpsxtraupdate}") if @gps_state == Constant::GPS_SWITCHED_OFF Log4Ienso.log.P_NOTICE("getGPSLocation: Setting up GPS") @connmanager.SetIsGPSSessionActive(true) rval = @connmanager.enableGPS() if rval.strip == "504" # gps session is active @accessgpstate.lock @gps_state = Constant::GPS_STARTED @accessgpstate.unlock Log4Ienso.log.P_NOTICE("getGPSLocation: GPS STARTED") @connmanager.setGPSState(@gps_state) end startTS = Time.now end Log4Ienso.log.P_INFO("getGPSLocation: GPS state is #{@gps_state}") if @gps_state == Constant::GPS_STARTED || @gps_state == Constant::GPS_FINDING_FIX lat, lng, errcode = @connmanager.getGPSData() Log4Ienso.log.P_INFO("getGPSLocation: Lat:#{lat} Lng:#{lng} ") @accessgpstate.lock @gps_state = Constant::GPS_FINDING_FIX @accessgpstate.unlock if is_numeric?(lat) || is_numeric?(lng) if lat != 0 && lng != 0 delta = Time.now - startTS @latitude = lat @longitude = lng $gpsTTFFcnt += 1 $gpsTTFFsum += delta Log4Ienso.log.P_WARN("GPS Fix Found!!! Lat:#{@latitude} Lng:#{@longitude} in #{delta}s") @accessgpstate.lock @gps_state = Constant::GPS_FIXED @accessgpstate.unlock @location_available = true @cut_off_time = Constant::GPS_DATA_TIME if @hotspot == 0 @connmanager.setGPSState(0) #let @connmanager.SetIsGPSSessionActive(false) break end end end end sleep Constant::GPS_CHECK_DELAY Thread.pass if count * Constant::GPS_CHECK_DELAY > (Constant::NO_GPS_DATA_TIME - 10) || @modem_state == Constant::MODEM_REBOOT Log4Ienso.log.P_NOTICE("Breaking out of GPS loop at count :#{count} and modem state #{@modem_state}") break end end @connmanager.stopGPS() Log4Ienso.log.P_CLEAN("<<<<<<<<<<<<<< Exiting GPS LOOP >>>>>>>>>>>>>>>>>>") end # sendPhotos executed in a thread def sendPhotos(mode) batch = 0 count = 0 checktoken = 0 thumb2=nil batch2=photoThreadCount2=modem_state2=0 #localtime = Time.now localtime = nil Log4Ienso.log.P_CLEAN("#{Time.now.strftime("%H:%M:%S.%L")} Starting sendPhotos thread") @photoThreadExited = false loop do #puts("sleep value is " + @env.get_env('wirless_on/off') ) if(@mutex_env.synchronize{@env.get_env('wirless_on/off')} == 'off') if ( @modem_state == Constant::MODEM_IDLE || @modem_state >= Constant::MODEM_CONNECTED ) #there is nothing to do lets sleep @connmanager.startModemSleepNormal(@wakeupcounter,@mutex_env.synchronize{@env.get_env_value('movie_length')}) break end end mode = Constant::UPLOAD_PHOTOS_AND_SERVER_CMDS if @overridePhotoUploadBlock == true #sms request for take photo now and upload, must change the mode if ( @modem_state >= Constant::MODEM_CONNECTED && mode == Constant::GET_SERVER_CMDS_ONLY && @continueUpload == 0) # just get server commands as requested over sms @connmanager.startModemSleepNormal(@wakeupcounter,@mutex_env.synchronize{@env.get_env_value('movie_length')}) @modem_state = Constant::MODEM_IDLE Log4Ienso.log.P_NOTICE("**************breaking at 1") break end #Log4Ienso.log.P_NOTICE("Modem state is #{@modem_state} photocount is #{count}") if (@modem_state >= Constant::MODEM_CONNECTED ) if (@modem_state != modem_state2) Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} -- send photo loop -- modem state=#{@modem_state}") modem_state2= @modem_state end localtime = Time.now if localtime == nil thumb = nil if batch < Constant::UPLOAD_BATCH_SIZE thumb = @picman.get_thumb_for_send_server() Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} -- send photo loop -- thumb=#{thumb}") batch+=1 if thumb != nil end if thumb == nil && ( @modem_state == Constant::MODEM_FINISHED_UPLOAD || @modem_state == Constant::MODEM_CONNECTED) #@modem_state = Constant::MODEM_IDLE Log4Ienso.log.P_ERR("#{Time.now.strftime("%H:%M:%S.%L")} -- send photo loop -- modem state=#{@modem_state}") @continueUpload = 0 end #if ( thumb == nil && @continueUpload == 0 && @modem_state == Constant::MODEM_IDLE ) #there is nothing to do lets sleep if ( thumb == nil && @continueUpload == 0 ) #there is nothing to do lets sleep @connmanager.setNextPhotoAvailable(false) @connmanager.startModemSleepNormal(@wakeupcounter,@mutex_env.synchronize{@env.get_env_value('movie_length')}) Log4Ienso.log.P_NOTICE("**************breaking at 2") break if @continueUpload == 0 end if thumb != nil && @photoThreadCount < Constant::MAX_PARALLEL_UPLOAD_LIMIT if checktoken == 0 @connmanager.checkToken checktoken = 1 end @th = Thread.new { send_thumb_to_server(thumb) } count += 1 Log4Ienso.log.P_NOTICE("____________________________________________________") Log4Ienso.log.P_NOTICE("Photos uploaded this session photocount is #{count}") Log4Ienso.log.P_NOTICE("____________________________________________________") end @connmanager.updateNetworkState if $model=="impulse" #check if network is still there end timediff = 0 timediff = (Time.now - localtime).abs if localtime != nil if timediff > 1000 localtime = Time.now timediff = 0 end if ( ((@modem_state == Constant::MODEM_REBOOT && @triedconnecting == 1 ) || ( timediff > Constant::PHOTO_UPLOAD_ABORT_TIME && @dailyMode == 0 )) && @otaupload == false ) Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} Aborting uploading .. modem state is: #{@modem_state} time is: #{timediff} dailymode #{@dailyMode}") @accessgpstate.lock @gps_state = Constant::GPS_ABORTED @accessgpstate.unlock @connmanager.setGPSState(0) #signal quectel to sleep if $final_test_flag != true @connmanager.startModemSleepAbort end break end if check_photo_mode sleep Constant::SEND_PHOTO_DELAY else sleep Constant::SEND_VIDEO_DELAY end Thread.pass end Log4Ienso.log.P_CLEAN("#{Time.now.strftime("%H:%M:%S.%L")} sendPhotos finish") @photoThreadExited = true end # executed in a thread def startModemandNetwork(networkname,starttype) count=1 @modemstarttime = Time.now Log4Ienso.log.P_CLEAN("#{Time.now.strftime("%H:%M:%S.%L")} startModemandNetwork: ---------------------------- Starting Modem Loop ---------------------------") loop do if @modem_state == Constant::MODEM_OFF || @modem_state == Constant::MODEM_CONNECTING #@modem_state = Constant::MODEM_CONNECTING if @connmanager == nil @connmanager = ConnectionManager.new(@config) @connmanager.add_listener(self) @triedconnecting = 1 #attempt made to connect to the network end status = @connmanager.startNetworkConnection(starttype,@wakeupcounter) $imei,$iccid = @connmanager.getIMEIandICCIDForMenu Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} startModemandNetwork: In control status=#{status} with imei=#{$imei} and iccid=#{$iccid}") if status == 0 rssi1 = @connmanager.getRSSI(1) @rssi = rssi1 if rssi1 != nil @view.set_rssi(@rssi) if @view != nil Log4Ienso.log.P_CLEAN("#{Time.now.strftime("%H:%M:%S.%L")} startModemandNetwork: Setting modem state to modem connected with RSSI #{@rssi} ") @modem_state = Constant::MODEM_CONNECTED break end count += 1 sleep (2) if count > Constant::MAX_NETWORK_TRY_COUNT || status == 1 || status == 5 || $iccid == "" Log4Ienso.log.P_NOTICE("startModemandNetwork: Aborting network connection opening") Log4Ienso.log.P_INFO("NO sim card.....") if $iccid == nil #$imei,$iccid = @connmanager.getIMEIandICCIDForMenu Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} startModemandNetwork: In control (abort) with #{$imei} and #{$iccid}") @thread_photo.kill if @thread_photo !=nil @connmanager.startModemSleepNormal(@wakeupcounter,@mutex_env.synchronize{@env.get_env_value('movie_length')}) break end end sleep(0.1) end while $final_test_flag == true # in the case of final test don't kill modem thread sleep(1) end Log4Ienso.log.P_CLEAN("#{Time.now.strftime("%H:%M:%S.%L")} startModemandNetwork: <<<<<<<<<<<<<>>>>>>>>>>>>>>>>> ///////// ") end def sd_card_mounted?() # the regex comparison (=~) returns the location of the match (positive # integer) or nil if there is not match not (`mount` =~ %r{/media/photos}).nil? end def camera_change_ir_led() val = 1 val = @comm.get_day_night() if @comm != nil if(val == 0) level = @mutex_env.synchronize{@env.get_env_value('led_power')} Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} set night IR LED level to#{level} ") @camera.set_ir_led_power(level) if @camera != nil end end def camera_get_set_day_night() val = 1 val = @comm.get_day_night() if @comm != nil if(val == 0) @camera.set_night if @camera != nil @view.set_day_and_night('night') if @view != nil else @camera.set_day if @camera != nil @view.set_day_and_night('day') if @view != nil end end def cameera_set_change(reason = {:day => false, :night => false}) if(reason[:day] == true) Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} reason = day, camera changed to day ") @camera.set_day @view.set_day_and_night('day') elsif(reason[:night] == true) Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} reason = night, camera changed to night ") @camera.set_night @view.set_day_and_night('night') else Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} get day or night from M0 and set camera based on it ") camera_get_set_day_night() end if(reason[:photocell]) photocell = @comm.get_photocell() @photocell_change_req_count +=1 @camera.light_lvl_change Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} Photocell changed #{photocell} count #{@photocell_change_req_count}") end end def get_lat_ref (deg) Log4Ienso.log.P_NOTICE("#{deg}") deg = deg.to_i if deg > 0 Log4Ienso.log.P_NOTICE(">>>>>>>>>>>>>>> NORTH #{deg}<<<<<<<<<<<<<<<<<<<<<<<<<") return "N " elsif deg < 0 Log4Ienso.log.P_NOTICE(">>>>>>>>>>>>>>> SOUTH #{deg}<<<<<<<<<<<<<<<<<<<<<<<<<") return "S" else return "-" # equator end end def get_long_ref (deg) Log4Ienso.log.P_NOTICE("#{deg}") deg = deg.to_i if deg > 0 Log4Ienso.log.P_NOTICE(">>>>>>>>>>>>>>> EAST #{deg}<<<<<<<<<<<<<<<<<<<<<<<<<") return "E" elsif deg < 0 Log4Ienso.log.P_NOTICE(">>>>>>>>>>>>>>> WEST #{deg}<<<<<<<<<<<<<<<<<<<<<<<<<") return "W" else return "-" #prime meridian end end def get_abs_deg (deg) if deg > 0 return deg else return -1*deg end end def makejson() exifTag = Hash.new() exifTag[:ImageDescription] = {:ifdType => 1, :tagId => 270,:tagType =>2 , :value => "Bushnell WTC" }; # "Bushnell WTC" exifTag[:Make] = "Bushnell" exifTag[:Model] = "Impulse" exifTag[:Orientation] = {:ifdType => 1, :tagId => 274,:tagType =>3 , :value => [1] }; # 1 exifTag[:XResolution] = {:ifdType => 1, :tagId => 282,:tagType =>5 , :value => [72] } #72 exifTag[:YResolution] = {:ifdType => 1, :tagId => 283,:tagType =>5 , :value => [72] } #72 exifTag[:ResolutionUnit] = {:ifdType => 1, :tagId => 296,:tagType =>3 , :value => [2] } #2 exifTag[:Software] = {:ifdType => 1, :tagId => 305,:tagType =>2 , :value => $firmware_ver} #@version.get_version() } #for save Software version @str1 = Time.now.strftime('%Y-%m-%dT%H:%M:%S') exifTag[:DateTime] = {:ifdType => 1, :tagId => 306,:tagType =>2 , :value => @str1 } #Time.now.strftime('%Y-%m-%dT%H:%M:%S') exifTag[:YCbCrPositioning] = {:ifdType => 1, :tagId => 531,:tagType =>3 , :value => [1] } #1 exifTag[:ExposureTime] = {:ifdType => 3, :tagId => 33434,:tagType =>5 , :value => [@camera.get_exposure()] } exifTag[:FNumber] = {:ifdType => 3, :tagId => 33437,:tagType =>5 , :value => [2.0]} # 2.0 exifTag[:ExifVersion] = {:ifdType => 3, :tagId => 36864,:tagType =>7 , :value => "0221" } # "0221" exifTag[:DateTimeOriginal] = Time.now.strftime('%Y-%m-%dT%H:%M:%S') #{:ifdType => 3, :tagId => 36867,:tagType =>2 , :value => @str2 } #Time.now.strftime('%Y-%m-%dT%H:%M:%S') #@nmea.dateTime exifTag[:DateTimeDigitized] = Time.now.strftime('%Y-%m-%dT%H:%M:%S') #{:ifdType => 3, :tagId => 36868,:tagType =>2 , :value => @str3 } #Time.now.strftime('%Y-%m-%dT%H:%M:%S') #@nmea.dateTime exifTag[:ShutterSpeedValue] = {:ifdType => 3, :tagId => 37377,:tagType =>5 , :value => [@camera.get_exposure()] } exifTag[:ApertureValue] = {:ifdType => 3, :tagId => 37378,:tagType =>5 , :value => [2.0] } # 2.0 exifTag[:BrightnessValue] = {:ifdType => 3, :tagId => 37379,:tagType =>10 , :value => [@camera.get_brightness()] } exifTag[:ExposureBiasValue] = {:ifdType => 3, :tagId => 37380,:tagType =>5 , :value => [0] } # 0 exifTag[:MaxApertureValue] = {:ifdType => 3, :tagId => 37381,:tagType =>5 , :value => [2.0] } # 2.0 exifTag[:MeteringMode] = {:ifdType => 3, :tagId => 37383,:tagType =>3 , :value => [4] } #4 exifTag[:LightSource] = {:ifdType => 3, :tagId => 37384,:tagType =>3 , :value => [0] } #0 val = @comm.get_day_night() if(val == 0) exifTag[:Flash] = {:ifdType => 3, :tagId => 37385,:tagType =>3 , :value => [1] } #1 else exifTag[:Flash] = {:ifdType => 3, :tagId => 37385,:tagType =>3 , :value => [0] } #0 end exifTag[:FocalLength ] = {:ifdType => 3, :tagId => 37386,:tagType =>5 , :value => [8.0] } #8.0 exifTag[:FlashPixVersion] = {:ifdType => 3, :tagId => 40960,:tagType =>7 , :value => "0100" } # "0100" exifTag[:ColorSpace] = {:ifdType => 3, :tagId => 40961,:tagType =>3 , :value => [1] } # 1 exifTag[:PixelXDimension] = {:ifdType => 3, :tagId => 40962,:tagType =>3 , :value => [72] } # 72 exifTag[:PixelYDimension] = {:ifdType => 3, :tagId => 40963,:tagType =>3 , :value => [72]} # 72 exifTag[:FileSource] = {:ifdType => 3, :tagId => 41728,:tagType =>7 , :value => [3] } # 3 exifTag[:ExposureMode] = {:ifdType => 3, :tagId => 41986,:tagType =>3 , :value => [0] } # 0 exifTag[:WhiteBalance] = {:ifdType => 3, :tagId => 41987,:tagType =>3 , :value => [0] } #0 exifTag[:DigitalZoomRatio] = {:ifdType => 3, :tagId => 41988,:tagType =>5 , :value => [1.0] } #1.0 exifTag[:SceneCaptureType] = {:ifdType => 3, :tagId => 41990,:tagType =>3 , :value => [0] } #0 exifTag[:GainControl] = {:ifdType => 3, :tagId => 41991,:tagType =>3 , :value => [0] } #0 exifTag[:Contrast] = {:ifdType => 3, :tagId => 41992,:tagType =>3 , :value => [0] } #0 exifTag[:Saturation] = {:ifdType => 3, :tagId => 41993,:tagType =>3 , :value => [0] } #0 exifTag[:Sharpness] = {:ifdType => 3, :tagId => 41994,:tagType =>3 , :value => [0] } #0 exifTag[:AnalogBalance] = {:ifdType => 3, :tagId => 50727,:tagType =>5 , :value => [@camera.get_gain()] } #0 exifTag[:InteroperabilityIndex] = {:ifdType => 5, :tagId => 1,:tagType =>2 , :value => "R98" } #"R98" exifTag[:InteroperabilityVersion] = {:ifdType => 5, :tagId => 2,:tagType =>7 , :value => "0100" } #"0100" if @mutex_env.synchronize{@env.get_env_value('embedded_gps')} == "on" exifTag[:GPSLatitudeRef] = get_lat_ref(@latitude).to_s exifTag[:GPSLatitude] = [get_abs_deg(@latitude).to_f] exifTag[:GPSLongitudeRef] = get_long_ref(@longitude).to_s exifTag[:GPSLongitude] = [get_abs_deg(@longitude).to_f] #exifTag[:GPSTimeStamp] = #exifTag[:GPSDateStamp] = end exifTag[:Custom1] = {:ifdType => 3, :tagId => 34033, :tagType =>5 , :value => [@t1_pulse] } exifTag[:Custom2] = {:ifdType => 3, :tagId => 34034, :tagType =>5 , :value => [@t2_pulse] } exifTag[:Custom3] = {:ifdType => 3, :tagId => 34035, :tagType =>5 , :value => [@t3_pulse] } t = (@mutex_env.synchronize{@env.get_env_value('trigger_time')}) case t when '50' tint = 50 when '70' tint = 70 when '90' tint = 90 when '100' tint = 100 else tint = 0 end puts("t is #{t} and tint=#{tint}") exifTag[:Custom4] = {:ifdType => 3, :tagId => 34036, :tagType =>5 , :value => [tint] } pir_sensitivity = (@mutex_env.synchronize{@env.get_selected_idx('pir')}) exifTag[:Custom5] = {:ifdType => 3, :tagId => 34037, :tagType =>5 , :value => [pir_sensitivity] } # it's Example how to insert unsupported Tag # typedef enum { # IFD_UNKNOWN = 0, # IFD_0TH, # IFD_1ST, # IFD_EXIF, # IFD_GPS, # IFD_IO # } IFD_TYPE; # typedef enum { # TYPE_BYTE = 1, # TYPE_ASCII, # TYPE_SHORT, # TYPE_LONG, # TYPE_RATIONAL, # TYPE_SBYTE, # TYPE_UNDEFINED, # TYPE_SSHORT, # TYPE_SLONG, # TYPE_SRATIONAL # } IFD_TAG_TYPE; # exifTag[:DateTime] = {:ifdType => 1, :tagId => 132,:tagType =>2 , :value => @nmea.dateTime }; x = JSON.generate(exifTag) exifTag = nil return x end def set_m0_time_zone() off_ons =@mutex_env.synchronize{@env.get_env('time_ofoperation.off_on')} times = @mutex_env.synchronize{@env.get_env('time_ofoperation.time')} off_ons.each_with_index do |off_on , days_idx| time = times[days_idx].split('/') off_on = off_on.split('/') off_on.each_with_index do | offon, blk_idx | time2 = time[blk_idx].split(':') Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} days=#{days_idx} block=#{blk_idx} offon=#{offon} hr=#{time2[0]} min=#{time2[1]} " ) packet=[0x0d, days_idx & 0xff, blk_idx & 0xff, offon.to_i & 0xff, int_to_bcd_bytes(time2[0].to_i) & 0xff, int_to_bcd_bytes(time2[1].to_i) & 0xff] ret=@comm.set_m0_time_zone(packet) end end end def initial_M0() @comm.set_photocell(@mutex_env.synchronize{@env.get_env_value('Set_photocell')}) @comm.set_picdelaytime(@mutex_env.synchronize{@env.get_env_value('imaage_interval')}) ret=set_m0_time_zone() set_field_scan() set_image_type() set_pir_mode() @comm.set_pir_sensitivity(@mutex_env.synchronize{@env.get_selected_idx('pir')}) if @comm != nil end def send_camera_name() name = @mutex_env.synchronize{@env.get_env_value('camera_name')} @camera.set_camera_name(name) if @camera != nil end def set_pir_mode_timer() idx1 = 0 if( @mutex_env.synchronize{@env.get_env_value('pir_mode')} == 'timer') idx = 4 idx1 = 1 packet=[0x0e, idx & 0xff] ret=@comm.set_m0_pir_mode(packet) end #@camera.set_pir_mode(idx1) if @camera != nil end def set_image_type() @camera.set_capture_type(@mutex_env.synchronize{@env.get_env_value('capture_mode')}) @camera.set_image_vid_resolution(@mutex_env.synchronize{@env.get_env_value('capture_mode')}) if(@mutex_env.synchronize{@env.get_env_value('capture_mode')} == 'image') length = @mutex_env.synchronize{@env.get_env_value('capture_count')} else length = @mutex_env.synchronize{@env.get_env_value('movie_length')} end @comm.set_image_type(@mutex_env.synchronize{@env.get_env_value('capture_mode')}, length) end def set_pir_mode() idx = @mutex_env.synchronize{@env.get_selected_idx('pir_mode') } idx1 = 0 if(idx > 2 ) if(idx > 3) idx = 16 else idx = 4 idx1 = 1 end end #@camera.set_pir_mode(idx1) if @camera != nil packet=[0x0e, idx & 0xff] ret=@comm.set_m0_pir_mode(packet) end def reset_default @mutex_env.synchronize{@env.reset_default()} if @env != nil @comm.set_default_settings() if @comm != nil @isMenuDirty = true end def set_file_logging() if @mutex_env.synchronize{@env.get_env_value('file_logging')} == 'on' @old_stdout = $stdout fo = File.new(Constant::LOG_FILE, 'a') $stdout = fo #ObjectSpace.define_finalizer(self, proc { $stdout = old_stdout }) @camera.request_logging(1, Constant::LOG_FILE) else $stdout = @old_stdout @camera.request_logging(0, Constant::LOG_FILE) end end def initial_menu menuL0 = MenuNodeSetup.new("menu", nil) l1 = MenuNodeSub.new("setup", menuL0) l1.add_listener(self) l2 = MenuNodeEnvValue.new("capture_mode", l1, get_env) {set_image_type(); @camera.set_frame_rate( )} l2 = MenuNodeSetTime.new("setime", l1) l2.add_listener(self) #l2 = MenuNodeEnvTimeOfOperation.new("time_ofoperation", l1, @mutex_env.synchronize{@env) #l2 = MenuNodeEnvValue.new("imaage_interval", l1, @mutex_env.synchronize{@env){@comm.set_picdelaytime(@mutex_env.synchronize{@env.get_env_value('imaage_interval'))} l2 = MenuNodeEnvValue.new("imaage_interval", l1, get_env) { @comm.set_picdelaytime(@mutex_env.synchronize{@env.get_env_value('imaage_interval')}) if(!check_photo_mode) @comm.set_image_type(@mutex_env.synchronize{@env.get_env_value('capture_mode')}, @mutex_env.synchronize{@env.get_env_value('movie_length')}) end } l2 = MenuNodeEnvValue.new("led_power", l1, get_env){ camera_change_ir_led() } l2 = MenuNodeEnvValue.new("show_timestamp", l1, get_env) {@camera.set_image_banner(@mutex_env.synchronize{@env.get_env_value('show_timestamp')}) } l2 = MenuNodeEnvPirMode.new("pir_mode", l1, get_env){set_pir_mode_timer()} l2.add_listener(self) l2 = MenuNodeEnvValue.new("report_interval", l1, get_env) l2 = MenuNodeEnvValue.new("embedded_gps", l1, get_env) l2 = MenuNodeEnvValue.new("pir", l1, get_env){ @comm.set_pir_sensitivity(@mutex_env.synchronize{@env.get_selected_idx('pir')}) if @comm != nil } l2 = MenuNodeEnvValue.new("overwrite", l1, get_env) #l2 = MenuNodeEnvValue.new("diagnostics", l1, get_env){ # system("rm -rf /var/log") # if(get_env.get_env('diagnostics') == 'on') # system("mkdir /var/log") # else # system("ln -sf /tmp /var/log") # end #} l2 = MenuNodeEnvSaveAsc.new("camera_name", l1, get_env){send_camera_name()} l2 = MenuNodeFormat.new("format_s/d", l1, get_env){ enter_special_func(); system("rm -rf /media/photos/DCIM/*") #TODO we should change it later system("rm -rf /media/photos/thumb/*") #TODO we should change it later system("sync") @picman.get_num_photos() if @picman != nil @picman.get_num_videos() if @picman != nil @picman.get_num_photos_videos() if @picman != nil #@picman.find_pic_vid_num if @picman != nil exit_special_func() } l2 = MenuNodeDefault.new("restore_default", l1, get_env){ enter_special_func(); reset_default() exit_special_func() } l2 = MenuNodeCallbackOnExecute.new("version check", l1) { @view.displayDiret("A: #{$firmware_ver}", 1, :left); @view.displayDiret("M:#{$version_m0}", 2, :left); sleep(4) } #l2 = MenuNodeTree.new("upgrade_firmware", l1) l2 = MenuNodeFileTree.new("upgrade_firmware",l1, "/media/photos/*.bnl"){ |path| upgradeFirmware(path) } #l3 = MenuNodeFileTree.new("Upgrade A83",l2, "/media/sd-mmcblk0p1/wtc_sd*.img"){ |path| upgradeFirmware(path) } #l3 = MenuNodeFileTree.new("Upgrade M0",l2, "/media/sd-mmcblk0p1/wtc_m0*.bin"){ |path| upgradeFirmwareM0(path) } if($developer_mode) l2 = MenuNodeTree.new("developer", l1) l3 = MenuNodeTree.new("config", l2) l4 = MenuNodeEnv.new("lcd_off_time",l3, get_env){ @timer_lcd_off.start(false, @mutex_env.synchronize{@env.get_env_value('lcd_off_time')}) } l3 = MenuNodeTree.new("take_pic", l2) l4 = MenuNodeCallback.new("take_pic_day", l3){ @wq_cap.enqueue_p(method(:take_picture),false, 1, :day); @wq_cap.join } l4 = MenuNodeCallback.new("take_pic_n", l3) { @wq_cap.enqueue_p(method(:take_picture),false, 1, :night); @wq_cap.join } l3 = MenuNodeEnv.new("trigger_time",l2, get_env) { t = (@mutex_env.synchronize{@env.get_env_value('trigger_time')}) puts("t is #{t}") @comm.set_trigger_timing(0) if t=='50' @comm.set_trigger_timing(1) if t=='70' @comm.set_trigger_timing(2) if t=='90' @comm.set_trigger_timing(3) if t=='100' } l3 = MenuNodeTree.new("DEBUG", l2) l4 = MenuNodeEnv.new("lcd_force_on", l3, get_env) l4 = MenuNodeEnv.new("Set_photocell",l3, get_env) { @comm.set_photocell(@mutex_env.synchronize{@env.get_env_value('Set_photocell')})} l4 = MenuNodeCallback.new("Get_photocell", l3) { val = @comm.get_photocell(); @view.displayDiret(" #{val} ", 2, :center); sleep(2)} l4 = MenuNodeCallback.new("PhotocellReqCnt", l3) { @view.displayDiret("#{@photocell_change_req_count}", 2, :center); sleep(2)} l4 = MenuNodeCallback.new("Upgrade Firmware", l3) { @view.displayDiret("#{@photocell_change_req_count}", 2, :center); sleep(2)} l4 = MenuNodeCallback.new("Upgrade OTA",l3) {val = devUpgradeFirmware ; @view.displayDiret("#{val}", 2, :left); sleep(2)} l4 = MenuNodeCallback.new("Enable HotSpot",l3) { val = enableHotspot; @view.displayDiret(" #{val} ", 2, :center); sleep(2)} l4 = MenuNodeCallback.new("Disable HotSpot",l3) { val = disableHotspot; @view.displayDiret(" #{val} ", 2, :center); sleep(2)} l4 = MenuNodeCallback.new("Start Streaming",l3) { val = startStreaming ; @view.displayDiret("#{val}", 2, :left); } l4 = MenuNodeCallback.new("Stop Streaming",l3) { val = endStreaming ; @view.displayDiret("#{val}", 2, :left); } l4 = MenuNodeCallback.new("Stop Tx/Rx",l3) { val = disableTxRx; @view.displayDiret(" #{val} ", 2, :left); sleep(2)} l4 = MenuNodeCallback.new("Start Tx/Rx",l3) { val = enableTxRx; @view.displayDiret(" #{val} ", 2, :left); sleep(2)} l4 = MenuNodeCallback.new("Zipit Errors",l3) { val = @connmanager.getStatusCode ; @view.displayDiret("#{val}", 2, :left); sleep(2)} l4 = MenuNodeCallback.new("Force Turn On",l3) { @comm.force_turn_on ; @view.displayDiret("#{val}", 2, :left); sleep(2)} l4 = MenuNodeCallback.new("Verizon APN Fix",l3) { enableVerizonDiagnostics() } l4 = MenuNodeCallback.new("Disable hrt bit",l3) { disable_heart_bit()} l4 = MenuNodeCallback.new("Enable hrt bit",l3) { enable_heart_bit()} l4 = MenuNodeCallback.new("Long wakup count",l3) { val = getNetworkMetrics; @view.displayDiret(" #{val} ", 2, :center); sleep(2)} l4 = MenuNodeCallback.new("Reset Counter ",l3) { @view.displayDiret("#{@m0_reset_counter1} #{@m0_reset_counter2} #{@power_reset_cntr}", 2, :left); sleep(2) } l4 = MenuNodeCallback.new("Clear Reset CNTR",l3) { @power_reset_cntr = 0 @env.save_env_val('reset_cntr', @power_reset_cntr.to_s) Log4Ienso.log.P_ERR("=================== warning: @power_reset_cntr=#{@power_reset_cntr } RESET TO ZERO======") sleep(1) } l4 = MenuNodeCallback.new("FILTER COUNTER ",l3) { @view.displayDiret("#{@fake_pmic_pir_cntr} #{@fake_pir_cntr} #{@nfake_pir_cntr}", 2, :left); sleep(2) } l4 = MenuNodeCallback.new("Clear FLTR CNTR",l3) { @fake_pmic_pir_cntr = 0 #@env.save_env_val('fake_pmic_pir_cntr', @fake_pmic_pir_cntr.to_s) @fake_pir_cntr = 0 #@env.save_env_val('fake_pir_cntr', @fake_pir_cntr.to_s) @nfake_pir_cntr = 0 #@env.save_env_val('nfake_pir_cntr', @nfake_pir_cntr.to_s) Log4Ienso.log.P_ERR("=================== warning: @fake_pir_cntr=#{@fake_pir_cntr } RESET TO ZERO======") sleep(1) } l3 = MenuNodeCallback.new("Version check", l2) {@view.displayDiret("M:#{$version_m0}", 2, :left); @view.displayDiret("A: #{$firmware_ver}", 1, :left); sleep(4) } l3 = MenuNodeFileTree.new("upgrade_firmware",l2, "/media/photos/*.bnl"){ |path| upgradeFirmware(path) } #l3 = MenuNodeFileTree.new("Upgrade M0",l2, "/media/sd-mmcblk0p1/wtc_m0*.bin"){ |path| upgradeFirmwareM0(path) } end l1 = MenuNodeSub.new("photo", menuL0) l2 = MenuNodeEnvValue.new("image_resoluition", l1, get_env) { if(check_photo_mode) @camera.set_resolution(@mutex_env.synchronize{@env.get_env_value('image_resoluition')}) puts '================= picture resolution changed============' end } l2 = MenuNodeEnvValue.new("capture_count", l1, get_env){ if(check_photo_mode) @comm.set_image_type(@mutex_env.synchronize{@env.get_env_value('capture_mode')}, @mutex_env.synchronize{@env.get_env_value('capture_count')}) puts '================= photo number changed============' end } l2 = MenuNodeEnvValue.new("shutter_speed", l1, get_env) { # This parameter is only valid for night photos. Daytime is always 'high' and is managed in the Camera class. if(@camera.get_day_night_state() == 'N') @camera.set_shutter_speed(@mutex_env.synchronize{@env.get_env_value('shutter_speed')}) else @camera.set_shutter_speed('high') end } l2 = MenuNodeEnvValue.new("pic_format", l1, get_env) { if(check_photo_mode) @camera.set_resolution(@mutex_env.synchronize{@env.get_env_value('image_resoluition')}) puts '================= picture format changed============' end } l2 = MenuNodeFieldScan.new("field_scan", l1, get_env) l2.add_listener(self) l1 = MenuNodeSub.new("video", menuL0) l2 = MenuNodeEnvValue.new("movie_resoluition", l1, get_env) { if(!check_photo_mode) @camera.set_resolution_video(@mutex_env.synchronize{@env.get_env('movie_resoluition')}) puts '================= video resolution changed============' end } l2 = MenuNodeEnvValue.new("movie_length", l1, get_env) { if(!check_photo_mode) @comm.set_image_type(@mutex_env.synchronize{@env.get_env_value('capture_mode')}, @mutex_env.synchronize{@env.get_env_value('movie_length')}) end } #l2 = MenuNodeEnvValue.new("imaage_interval", l1, @mutex_env.synchronize{@env) { # if(!check_photo_mode) # @comm.set_image_type(@mutex_env.synchronize{@env.get_env_value('capture_mode'), @mutex_env.synchronize{@env.get_env_value('movie_length')) # end #} #l2 = MenuNodeEnvValue.new("movie_led_power", l1, @mutex_env.synchronize{@env) l2 = MenuNodeEnvValue.new("hybrid", l1, get_env) {@camera.set_hybrid(@mutex_env.synchronize{@env.get_env_value('hybrid')})} l1 = MenuNodeSub.new("network", menuL0) l2 = MenuNodeEnvValue.new("wirless_on/off", l1, get_env){ if(@mutex_env.synchronize{@env.get_env('wirless_on/off')} == 'on') @picman.resend_pic updateNetwork(@mutex_env.synchronize{@env.get_env_value('Select_Network')}) end } l2 = MenuNodeEnvTracking.new("tracking", l1, get_env){ if(@mutex_env.synchronize{@env.get_env('tracking')} == 'off') @comm.enable_theft_mode @mutex_env.synchronize{@env.save_env_val('tracking', "on")} @trackingstate = 1 $tracking_enabled_oncamera = true Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} ....tracking was enabled....") end #tracking mode cannot be switched off from the menu #else # @comm.disable_theft_mode # Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} ....tracking was disabled....") #end } #l2 = MenuNodeEnvValue.new("network_settings", l1, @mutex_env.synchronize{@env) l2 = MenuNodeSendTestImage.new("send_test_image", l1, get_env){ send_image_to_network()} l2 = MenuNodeTree.new("DIAGNOSTICS", l1) #l3 = MenuNodeEnv.new("Select_Network", l2, @mutex_env.synchronize{@env){updateNetwork(@mutex_env.synchronize{@env.get_env_value('Select_Network'))} #l3 = MenuNodeCallback.new("Copy Log to SD", l2) { # if sd_card_mounted? # enter_special_func(); # system("cp /var/log/messages* /media/photos/") # system("dmesg > /media/photos/dmesg") # system("sync") # exit_special_func() # end # } l3 = MenuNodeEnv.new("file_logging", l2, get_env){ set_file_logging() } l3 = MenuNodeCallback.new("COPY LOG TO SD", l2) { if sd_card_mounted? enter_special_func(); if @mutex_env.synchronize{@env.get_env_value('file_logging')} == 'on' #redirect stdout first then delete file $stdout = @old_stdout @camera.request_logging(0, Constant::LOG_FILE) end #in_files_dir = Dir["/var/wtc2.0/messages*"] in_files_dir = Dir["/var/log/messages*"] in_files_dir.each do |in_file_path| #in_file_name = in_file_path.split('/wtc2.0/') in_file_name = in_file_path.split('/log/') out_file_path = "/media/photos/" + in_file_name[1] @camera.request_encrypt(in_file_path, out_file_path) #system("cp /var/wtc2.0/messages* /media/photos/") end in_files_dir = Dir["/var/loghist/*"] in_files_dir.each do |in_file_path| #in_file_name = in_file_path.split('/wtc2.0/') in_file_name = in_file_path.split('/loghist/') out_file_path = "/media/photos/" + in_file_name[1] @camera.request_encrypt(in_file_path, out_file_path) #system("cp /var/wtc2.0/messages* /media/photos/") end #system("dmesg > /media/photos/dmesg") system("dmesg > /var/log/dmesg") system("sync") in_file = "/var/log/dmesg" out_file = "/media/photos/dmesg" @camera.request_encrypt(in_file, out_file) system("rm -rf /var/log/messages*") system("sync") if @mutex_env.synchronize{@env.get_env_value('file_logging')} == 'on' #redirect back to file @old_stdout = $stdout fo = File.new(Constant::LOG_FILE, 'a') $stdout = fo @camera.request_logging(1, Constant::LOG_FILE) end exit_special_func() end } l3 = MenuNodeCallback.new("CONNECTION",l2) { val = @connmanager.isConnected if @connmanager != nil ; @view.displayDiret("#{val}", 2, :left); sleep(2)} l3 = MenuNodeCallback.new("IP ADDR",l2) { val = @connmanager.getIPaddr if @connmanager != nil; @view.displayDiret(" #{val} ", 2, :center); sleep(2)} l3 = MenuNodeCallback.new("RSSI",l2) { val = @rssi; @view.displayDiret(" #{val} ", 2, :center); sleep(2)} l3 = MenuNodeCallback.new("UPLOAD COUNT",l2) { val = @upload_photo_count; @view.displayDiret(" #{val} ", 2, :center); sleep(2)} l3 = MenuNodeCallback.new("IMEI",l2) { imei1 = "IMEI: " + $imei[0..-13]; imei2 = $imei[-12..-1]; @view.displayDiret("#{imei1}", 1, :left); @view.displayDiret("#{imei2}", 2, :left); sleep(2)} l3 = MenuNodeCallback.new("ICCID",l2) { iccid1 = "ICCID: " + $iccid[0..-14]; iccid2 = $iccid[-13..-1]; @view.displayDiret("#{iccid1}", 1, :left); @view.displayDiret("#{iccid2}", 2, :left); sleep(2)} l3 = MenuNodeCallback.new("RESET UPLOAD COUNT",l2) { val = resetUploadCount ; @view.displayDiret("#{val}", 2, :left); sleep(2)} l3 = MenuNodeCallback.new("RESET MODEM",l2) { val = resetModemValue ; @view.displayDiret("#{val}", 2, :left); sleep(2)} #l3 = MenuNodeCallback.new("Upgrade Firmware",l2) {val = devUpgradeFirmware ; @view.displayDiret("#{val}", 2, :left); sleep(2)} #l3 = MenuNodeCallback.new("TRACKING ON ",l2) { @comm.enable_theft_mode ; @view.displayDiret("#{val}", 2, :left); sleep(2)} #l3 = MenuNodeCallback.new("TRACKING OFF ",l2) { @comm.disable_theft_mode ; @view.displayDiret("#{val}", 2, :left); sleep(2)} menuL0 end def devUpgradeFirmware msg="" if @firmwareRemoteRequest == 0 @firmwareRemoteRequest = 1 msg = "Enabled: Wait for network" elsif @firmwareRemoteRequest == 1 @firmwareRemoteRequest = 0 msg = 'Disabled' end return msg end def send_image_to_network enter_special_func(); if(@mutex_env.synchronize{@env.get_env('wirless_on/off')} == 'off') @view.displayDiret("TURN WIRELESS ON", 1, :left) @view.displayDiret("AND RE-TRY .. ", 2, :left) Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} ....wireless is off ,turn it on and retry....") sleep(3) exit_special_func() return end Log4Ienso.log.P_NOTICE("stariting photo send") @timer_imagetest.start(false, 6) @image_to_network_try = 0 @upload_photo_count_copy = @upload_photo_count @wq_cap.enqueue_p(method(:take_picture), false, 1) @menu_test_image = 1 # ignore PIR for now @connmanager.setNextPhotoAvailable(true) Log4Ienso.log.P_NOTICE(">>>>RESETTING MODEM <<<<<<") @thread_modem.kill if @thread_modem != nil @thread_photo.kill if @thread_photo != nil # MPD Moved to sleepModem - system(%Q(/opt/wtc2.0/src/sleep.sh)) @connmanager.sleepModem() @modem_state = Constant::MODEM_OFF @thread_modem = Thread.new { Log4Ienso.log.P_NOTICE(">>>>STARTING MODEM <<<<<<") startModemandNetwork(@mutex_env.synchronize{@env.get_env_value('Select_Network')}, @starttype) @starttype = Constant::RESUME_WAKEUP if @starttype == Constant::COLD_BOOT } Log4Ienso.log.P_NOTICE(">>>>>>>>>>>>>>>>>>>> modem started <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<") @thread_photo = Thread.new { sendPhotos(Constant::UPLOAD_PHOTOS_AND_SERVER_CMDS) } Log4Ienso.log.P_NOTICE(">>>>>>>>>>>>>>>>>>>>send photo started <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<") @view.displayDiret("SENDING IMAGE ", 1, :left) @view.displayDiret("PLEASE WAIT... ", 2, :left) Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} ....sending image to network started......") @update_view_flag = false @view.view_update() end def enableVerizonDiagnostics() Log4Ienso.log.P_NOTICE(">>>> Starting Verizon APN Reset <<<<<<") @timer_verizonreset.start(false, 6); if @modem_state < Constant::MODEM_PORTS_AVAILABLE Log4Ienso.log.P_NOTICE(">>>>RESETTING MODEM <<<<<<") @thread_modem.kill if @thread_modem != nil @thread_photo.kill if @thread_photo != nil # MPD Moved to sleepModem - system(%Q(/opt/wtc2.0/src/sleep.sh)) @connmanager.sleepModem() @modem_state = Constant::MODEM_OFF @thread_modem = Thread.new { Log4Ienso.log.P_NOTICE(">>>>STARTING MODEM <<<<<<") startModemandNetwork(@mutex_env.synchronize{@env.get_env_value('Select_Network')}, @starttype) @starttype = Constant::RESUME_WAKEUP if @starttype == Constant::COLD_BOOT } Log4Ienso.log.P_NOTICE(">>>>>>>>>>>>>>>>>>>> modem started <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<") end @view.displayDiret("PLEASE WAIT ", 1, :left) @view.displayDiret("Enabling Modem... ", 2, :left) end def resetVerizonAPN(test) count = 0 Log4Ienso.log.P_NOTICE(">>>> Waiting for modem <<<<<<") while @modem_state < Constant::MODEM_PORTS_AVAILABLE sleep(0.2) count+=1 if count.even? @view.displayDiret("Enabling Modem - ", 2, :left) else @view.displayDiret("Enabling Modem | ", 2, :left) end if count > 20 Log4Ienso.log.P_NOTICE(">>>> Modem Failed <<<<<<") @view.displayDiret("Failed to connect to modem", 2, :left) break end end if @modem_state >= Constant::MODEM_PORTS_AVAILABLE Log4Ienso.log.P_NOTICE("|||| Modem connected |||||||") system(%Q(/opt/wtc2.0/src/verizon.sh)) Log4Ienso.log.P_NOTICE("|||| Script executed |||||||") #@connmanager.fixSIM @view.displayDiret("Verizon APN updated", 1, :left) @view.displayDiret("REBOOT CAMERA !", 1, :left) end end def check_wakeup_reason_timer(test) Log4Ienso.log.P_MAGENTA("#{Time.now.strftime("%H:%M:%S.%L")} !!! it's pir from m0 so check pir for fake !!!") reason = @comm.check_wakeup_reason(2) if @comm != nil if reason != nil if ( reason[:pir] == false) @fake_pir_flag = true increment_fake_pir_cntr() else @fake_pir_flag = false increment_nfake_pir_cntr() if ((reason[:field_scan] == false) && (reason[:field_scanb] == false)) end Log4Ienso.log.P_YELLOW("====@fake_pmic_pir_cntr=#{@fake_pmic_pir_cntr } AND @fake_pir_cntr=#{@fake_pir_cntr } AND @not_fake_pir_cntr=#{@nfake_pir_cntr }===\n") end end def check_send_image_to_network (test) if (@upload_photo_count_copy < @upload_photo_count) @view.displayDiret("SUCCESSFUL... ", 2, :left) Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} ....sending image to network successful......") else if(@image_to_network_try < 5) @image_to_network_try += 1 #try again @timer_imagetest.start(false, 5); return else @view.displayDiret("FAILED ... ", 2, :left) Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} ....sending image to network failed......") end end sleep(3) @update_view_flag = true @menu_test_image = 0 # enable PIR @connmanager.setNextPhotoAvailable(false) exit_special_func(); end def enable_heart_bit @heart_bit_flag = true @heart_bit_timer_started_flag = true @timer_heart_bit.start(false, 5); end def disable_heart_bit @heart_bit_flag = false @comm.disable_heart_bit() if @comm != nil @timer_heart_bit.start(false, 'never') end def heart_bit(test) @heart_bit_timer_started_flag = false if (@heart_bit_flag == false) return end @comm.send_heart_bit(@hbit_timeout) if @comm != nil end def check_heart_bit if (@heart_bit_flag && !@heart_bit_timer_started_flag) @heart_bit_timer_started_flag = true @timer_heart_bit.start(false, 5) end end def banner(test) if (@timer_banner_flag == false) return end @banner_cntr +=1 case @banner_cntr when 1 str = "copying. " when 2 str = "copying.. " when 3 str = "copying... " else @banner_cntr =0 str = "copying...." end @view.displayDiret(str, 2, :center) @timer_banner.start(false, 0.5) end def renew_env @mutex_env.synchronize{ @env = nil @env = Env.new(@config.def_env) } end def get_env @mutex_env.synchronize{ @env } end def refreshMenu #enter_special_func(); #@env = nil #@env = Env.new(@config.def_env) renew_env() @view.refreshMenu(get_env,initial_menu()) if @view != nil #send_camera_name() #exit_special_func() return "refreshed" end def enableHotspot wlan="" if @hotspot == 0 #enter_special_func(); @mqtt_th.kill if @mqtt_th != nil @mqtt_th = Thread.new{ getMqttMessages } Log4Ienso.log.P_NOTICE("MQTT started") if @startmode == Constant::COLD_BOOT or @hotspotactivated == 0 puts("starting in cold mode") @hotspotactivated = 1 `killall hostapd | sh` sleep(4) `modprobe -v 8723bs` sleep(1) system("/opt/wtc2.0/src/enablehotspot.sh &") sleep(3) wlan = `ifconfig -a | cut -d" " -f1 | grep w | head -1` if wlan == nil or wlan =="" return "Failed" end system("/usr/bin/ruby -I /opt/wtc2.0/src -I /opt/wtc2.0/lib/ /opt/wtc2.0/src/webserver.rb -o 0.0.0.0 &") elsif @startmode == Constant::RESUME_WAKEUP puts("starting in warm mode") `killall hostapd | sh` sleep(4) `modprobe -v 8723bs` sleep(1) #`/usr/sbin/hostapd -B /etc/hostapd.conf & | sh` system("/opt/wtc2.0/src/enablehotspot.sh &") wlan = `ifconfig -a | cut -d" " -f1 | grep w | head -1` if wlan == nil or wlan =="" return "Failed" end system("/usr/bin/ruby -I /opt/wtc2.0/src -I /opt/wtc2.0/lib/ /opt/wtc2.0/src/webserver.rb -o 0.0.0.0 &") end @hotspot = 1 @cut_off_time = Constant::WIFI_TIME #change the time to sleep #sleep(0.1) #system("/opt/wtc2.0/src/streamf.sh") end # return ":On " + wlan end def disableHotspot if @hotspot == 1 @hotspot = 0 system("/opt/wtc2.0/src/disablewebserver.sh") Log4Ienso.log.P_INFO("Shutting down hotspot and web server") $gps_wakeup_flag = true @updateServer = 1 #`killall hostapd` if @streaming == Constant::STREAMING_ON @streaming = Constant::STREAMING_OFF @camera.stop_streaming end #@comm.interrupt_mask(false) #@timer_lcd_off.start(false, @mutex_env.synchronize{@env.get_env_value('lcd_off_time')}) @cut_off_time = Constant::GPS_DATA_TIME @modem_state = Constant::MODEM_IDLE return "Hotspot Off" end end def resetModemValue `rm /var/wtc2.0/lte.config` return "Reboot camera" end def disableTxRx if @connmanager != nil r = @connmanager.stopTxRx return r end return "Modem offline" end def enableTxRx if @connmanager != nil r = @connmanager.startTxRx return r end return "Modem online" end def startStreaming if @streaming == Constant::STREAMING_OFF && @hotspot == 1 Log4Ienso.log.P_INFO("------Calling camera instance") @camera.start_streaming(0) Log4Ienso.log.P_INFO("-----camera instance called") @streaming = Constant::STREAMING_ON #system("/opt/wtc2.0/src/streamf.sh &") return "streaming..." else return "hotspot off" if @hotspot=="0" end end def endStreaming if @streaming == Constant::STREAMING_ON #@hotspot = 0 @streaming = Constant::STREAMING_OFF @camera.stop_streaming #system("/opt/wtc2.0/src/disablehotspotetstreaming.sh") return "Streaming Off" end return "Streaming is off" end def resetUploadCount `echo 0 > /var/wtc2.0/uploadcount.counter` @upload_photo_count = 0 return "Counter reset" end def updatePhotoUploadCount if @startmode == Constant::COLD_BOOT if !File.exists?('/var/wtc2.0/uploadcount.counter') `touch /var/wtc2.0/uploadcount.counter` else c = `cat /var/wtc2.0/uploadcount.counter` @upload_photo_count = c.chomp.strip.to_i end else `echo #{@upload_photo_count} > /var/wtc2.0/uploadcount.counter` end end # temporary function required until we need to change sim cards, remove in final version # when sim card is known def updateNetwork(networkname) #ConnectionManager.setConnectionParameters(networkname,@config) end def enter_special_func @timer_lcd_off.start(false, 'never') @comm.interrupt_mask(true) end def exit_special_func @comm.interrupt_mask(false) @timer_lcd_off.start(false, @mutex_env.synchronize{@env.get_env_value('lcd_off_time')}) end def upgradeFirmware(path) imgfile = path if File.exists?(imgfile) Log4Ienso.log.P_NOTICE("Download #{imgfile}") enter_special_func() disable_heart_bit() sleep (0.1) @comm.set_upgrade_flag() if @comm != nil if (@thread_gps != nil) @thread_gps.kill Log4Ienso.log.P_NOTICE("(upgrade firmware)FORCING modem shutdown...killed gps thread...#{@gps_state} #{@modem_state} ") end if (@thread_modem != nil) @thread_modem.kill Log4Ienso.log.P_NOTICE("(upgrade firmware)FORCING modem shutdown...killed modem thread...#{@gps_state} #{@modem_state} ") end if (@thread_photo != nil) @thread_photo.kill Log4Ienso.log.P_NOTICE("(upgrade firmware)FORCING modem shutdown...killed photo thread...#{@gps_state} #{@modem_state} ") end @accessgpstate.lock @gps_state = Constant::GPS_ABORTED @accessgpstate.unlock @connmanager.shutdownModem @modem_state = Constant::MODEM_REBOOT @view.displayDiret("UPGRADE FIRMWARE", 1, :left) @view.displayDiret("copying....", 2, :center) @timer_banner.start(false, 0.5); @timer_banner_flag = true Log4Ienso.log.P_INFO("Upgrade Firmware Start") # do rotation ret = @camera.request_upgrade (imgfile) ret = ret.to_i @timer_banner_flag = false sleep(0.5) if( ret == 0) Log4Ienso.log.P_NOTICE("=========== Download success =====") Log4Ienso.log.P_INFO("Upgrade Firmware End") @view.displayDiret("SUCCESS ", 1, :left) else Log4Ienso.log.P_NOTICE("============ WARNING: Download failed error code=#{ret} =======") @view.displayDiret("Upgrade Failed ", 1, :left) @view.displayDiret("Press Key Reboot", 2, :left) @store_key_pressed_flag = true #wait for any key to be pressed loop do @keypressed = nil while @keypressed == nil sleep (0.5) end #if (@keypressed == 'Enter') break #else # next #end end end @view.displayDiret("REBOOTING... ", 2, :left) sleep(2) @view.displayOff() system('reboot') system('sync') else @view.displayDiret("A83M0 Upgrade ", 1, :left) @view.displayDiret("File not found ", 2, :left) Log4Ienso.log.P_INFO("Upgrade Firmware Fail : file not found") sleep(1) end end def setDefaultTime dtcheck=`date +%Y` #get the year dtcheck = dtcheck.chomp.strip if dtcheck == "1970" Log4Ienso.log.P_INFO("Setting default time to 2018/01/01") datestr = "2018 01 01 07 00 00" Log4Ienso.log.P_INFO("System data to be set is >>>>>>>>>>>>>>>>>> " + datestr.to_s) dt = DateTime.strptime( datestr , '%Y %m %d %H %M %S' ) tt = Time.parse(dt.to_s).getlocal.to_s tta = tt.split("+") Log4Ienso.log.P_INFO(tta[0].to_s) cmd = "date -s \"" +tta[0].to_s.strip + "\"" Log4Ienso.log.P_INFO("the final command is >>> " + cmd.to_s) Log4Ienso.log.P_INFO(cmd) system(cmd) system("hwclock --systohc") #update hardware clock end end def upgradeFirmwareM0(path) #binfile = "/media/sd-mmcblk0p1/wtc_m0*.bin" #binfile = "/media/photos/wtc_m0*.bin" #if File.exists?(binfile) == false # binfile = "/media/sd-mmcblk0p1/wtc_m0*.bin" #end #my_dir = Dir[binfile] #my_dir.sort! {|x,y|y<=>x} #binfile = my_dir[0] #@comm = nil; binfile = path if File.exists?(binfile) Log4Ienso.log.P_INFO("Upgrade M0 Firmware Start #{binfile}") @view.displayDiret("M0 Upgrade", 1, :center) @view.displayDiret("copying..", 2, :center) enter_special_func() @comm.download_firmware(binfile) @view.displayDiret("SUCCESS", 2, :center) sleep(1) exit_special_func() Log4Ienso.log.P_INFO("Upgrade M0 Firmware End") else @view.displayDiret("M0 Upgrade", 1, :center) @view.displayDiret("Fail", 2, :center) sleep(1) Log4Ienso.log.P_INFO("Upgrade M0 Firmware Fail") end end # This methods handles events that were generated by EventSource that we registered to. # See new for a list of sources to which we register. def handle_event(event, data = nil) # Camera has finished capturing an image. if event =~ %r{keypad/keypress} Log4Ienso.log.P_YELLOW("\n#{Time.now.strftime("%H:%M:%S.%L")} In control: the key pressed is #{data[:name].to_s}\n") if($final_test_flag || @store_key_pressed_flag ) @keypressed = data[:name] else if((@mutex_sleep != nil)&&( @mutex_sleep.try_lock == true)) if(@view.displayOn? == true) setSignalStrengthLeds() #switch on @timer_lcd_off.start(false, @mutex_env.synchronize{@env.get_env_value('lcd_off_time')}) Log4Ienso.log.P_YELLOW("\nIn control: setSignalStrengthLeds() and @timer_lcd_off.start \n") end #if(@view.displayOn? == false) # @view.init_lcd(true) # @view.displayOn() # Log4Ienso.log.P_YELLOW("\nIn control: @view.displayOn() \n") #end @mutex_sleep.unlock else Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} =============Warning: Event keypad/keypress ignored because of mutex_sleep could not be locked") end end elsif event =~ %r{keypad/developer_mode} @isMenuDirty = true elsif event =~ %r{view/shut_down} Log4Ienso.log.P_YELLOW("\n#{Time.now.strftime("%H:%M:%S.%L")} In control: view/shut down\n") @comm.a83_power_down() if @comm != nil sleep 0.5 system("poweroff") elsif event =~ %r{comm/interrupted} Log4Ienso.log.P_YELLOW("\n#{Time.now.strftime("%H:%M:%S.%L")} In control: comm/interrupted data is #{data.to_s}\n") if $final_test_flag && (data[:pir] == true) sleep(0.2) #(FAKE_PIR_WAIT_TIME) check_wakeup_reason_timer(false) if !@fake_pir_flag count_pir_final_test() if @final_test_start_time == nil @final_test_start_time = Time.now Log4Ienso.log.P_YELLOW("\n#{Time.now.strftime("%H:%M:%S.%L")} In control: first pir final test is #{@final_test_start_time.to_s}\n") end @fake_pir_flag = false end @comm.send_vid_pic_end() if @comm != nil $pir_confirmation_flag = false if $pir_confirmation_flag return end # checking displayOn added to make sure "if display is on not to take picture because of pir" if($video_recording == false) if((data[:pir] == true) && (@view.displayOn? == true)) #if(data[:pir] == true || data[:field_scan] == true || data[:field_scanb] == true) && check_photo_mode() @comm.send_vid_pic_end() if @comm != nil $pir_confirmation_flag = false if $pir_confirmation_flag end if(((data[:pir] == true) && (@view.displayOn? == false)) || (data[:field_scan] == true) || (data[:field_scanb] == true)) idx = 0 if(data[:pir] != true) idx =1 else #@th = Thread.new{ sleep(0.2) #(FAKE_PIR_WAIT_TIME) check_wakeup_reason_timer(false) #} end @camera.set_pir_mode(idx) if @camera != nil @camera.set_temp(@comm.get_temp) if @camera != nil $pir_confirmation_flag = false if $pir_confirmation_flag pir_detected() else cameera_set_change(data) end else if(data[:pir] == true || data[:field_scan] == true || data[:field_scanb] == true) @comm.send_vid_pic_end() if @comm != nil end end if ( (data[:power_button] == true) || (data[:accelerometer] == true) ) @turn_on_display_flag = true end if (data[:sms] == true) Log4Ienso.log.P_INFO("||||| SMS received when awake, postponing until next wakeup - will pickup instruction from server |||||") $gps_wakeup_flag = true if @starttype != Constant::COLD_BOOT end if (data[:theftmode] == true) Log4Ienso.log.P_INFO("||||| Theft mode activated |||||") end if (data[:a83_awake] == true) @wakeupcounter += 1 Log4Ienso.log.P_INFO("||||| gps awakening to get location wakeupcounter=#{@wakeupcounter} |||||") # check to initiate gps get location end elsif event =~ %r{comm/interrupt_accelerometer} @turn_on_display_flag = true elsif event =~ %r{sdcard/inserted} #if @comm != nil # @comm.send_heart_bit(300) #else # Log4Ienso.log.P_ERR("#{Time.now.strftime("%H:%M:%S.%L")} WARNING:can not send heart bit change in reading sd card time ") #end @sdcard_status = true chk_final_test_sw() chk_test_server_enabled elsif event =~ %r{sdcard/removed} @sdcard_status = false elsif event =~ %r{sdcard/diskSpace} @disk_space = data elsif event =~ %r{modem/started} Log4Ienso.log.P_NOTICE("modem start evemt") @modem_state = Constant::MODEM_CONNECTING elsif event =~%r{modem/continueupload} Log4Ienso.log.P_NOTICE("continue upload event") if @modem_state == Constant::MODEM_REBOOT || @modeSDCardRead == Constant::DONOT_READ_SD_CARD Log4Ienso.log.P_NOTICE("continue upload event ignored") else @continueUpload = 1 @connmanager.setNextPhotoAvailable(true) end #@modem_state = Constant::MODEM_CONNECTED elsif event =~ %r{modem/usbconnected} #Log4Ienso.log.P_NOTICE("modem ports avaialble") rssi1 = @connmanager.getRSSI(1) @rssi = rssi1 if rssi1 != nil Log4Ienso.log.P_CLEAN("#{Time.now.strftime("%H:%M:%S.%L")} /modem/usbconnected event detected >>> modem ports avaialble with RSSI #{@rssi} ") sleep(0.5) $imei,$iccid = @connmanager.getIMEIandICCIDForMenu @modem_state = Constant::MODEM_PORTS_AVAILABLE elsif event =~ %r{modem/connected} Log4Ienso.log.P_NOTICE("modem connected event received") @modem_state = Constant::MODEM_CONNECTED #if @startmode != Constant::COLD_BOOT # @comm.set_m0_rtc() #end elsif event =~ %r{modem/clock_updated} Log4Ienso.log.P_NOTICE("modem clock updated event received") @comm.set_m0_rtc() if @gpsxtraupdate == false @gpsxtraupdate = @connmanager.updateGPSFromFTP() end @time_updated = true elsif event =~ %r{modem/getting_ip_failed} $ip_failed_cntr += 1 Log4Ienso.log.P_ERR("#{Time.now.strftime("%H:%M:%S.%L")} ...WARNING... : TRIED SEVERAL TIME TO GET IP ADDRESS AND FAILED, $ip_failed_cntr=#{$ip_failed_cntr}") @modem_state = Constant::MODEM_REBOOT @continueUpload = 0 if $ip_failed_cntr >= 5 $ip_failed_cntr = 0 Log4Ienso.log.P_ERR("=================== @power_reset_cntr=#{@power_reset_cntr } ======") @reboot_flag = true @starttype = Constant::COLD_BOOT @cut_off_time = Constant::NO_GPS_DATA_TIME end elsif event =~ %r{modem/ignore_pir} Log4Ienso.log.P_CLEAN("#{Time.now.strftime("%H:%M:%S.%L")} ignore pir triggers while uploading ------ thread_count=#{@photoThreadCount}") @comm.ignore_pir() if @comm != nil elsif event =~ %r{modem/resume_pir} Log4Ienso.log.P_CLEAN("#{Time.now.strftime("%H:%M:%S.%L")} resume pir triggers after uploading ------ thread_count=#{@photoThreadCount}") @comm.resume_pir() if @comm != nil elsif event =~ %r{http/imgresolution} updateImageResolution elsif event =~ %r{http/movieresolution} updateMovieResolution elsif event =~ %r{http/pirmode} updatePirMode elsif event =~ %r{http/fieldscan} updateFieldScan elsif event =~ %r{http/pirdelay} updatePirDelay elsif event =~ %r{http/pirsensitivity} updatePIRSensitivity elsif event =~ %r{http/ledintensity} updateledIntensity elsif event =~ %r{http/movielength} updateMovieLength elsif event =~ %r{http/shutterspeed} updateShutterSpeed elsif event =~ %r{http/showtimestamp} updateTimeStamp elsif event =~ %r{http/capture_mode} updateCaptureMode elsif event =~ %r{http/tracking} Log4Ienso.log.P_NOTICE("########### tracking changed #{data[:tracking]}") #if(@mutex_env.synchronize{@env.get_env('tracking')} == 'on') if data[:tracking] == true @comm.enable_theft_mode $tracking_enabled_oncamera = true @mutex_env.synchronize{ @env.save_env_val('tracking', "on") } @trackingstate = 0 #tracking is just enabled, not active as yet Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} ....tracking was enabled, but not active....") else @comm.disable_theft_mode @trackingstate = 0 $tracking_enabled_oncamera = false @mutex_env.synchronize { @env.save_env_val('tracking', "off") } @mutex_env.synchronize { @env.save_env_val('gps_tracking', "off") } Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} ....tracking was disabled....") end refreshMenu @camera.refreshEnv(get_env) elsif event =~ %r{http/timeofoperation} updateTimeOfOperation elsif event =~ %r{modem/startingupload} Log4Ienso.log.P_NOTICE("modem starting photo upload") @modem_state = Constant::MODEM_STARTING_UPLOAD elsif event =~ %r{modem/finishedupload} Log4Ienso.log.P_NOTICE("completed photo upload") @modem_state = Constant::MODEM_FINISHED_UPLOAD @continueUpload = 0 elsif event =~ %r{modem/fail} Log4Ienso.log.P_NOTICE("modem or network lost") @modem_state = Constant::MODEM_OFF elsif event =~ %r{modem/sleeping} Log4Ienso.log.P_NOTICE("modem sleeping set modem_state to IDLE") @modem_state = Constant::MODEM_IDLE @continueUpload = 0 elsif event =~ %r{modem/reboot} if $model == "impulse" Log4Ienso.log.P_NOTICE("modem needs reboot") #@comm.a83_sleeping() if @comm != nil if @photoThreadCount == 0 @modem_state = Constant::MODEM_REBOOT @continueUpload = 0 end if @dailyMode == 1 #in the middle of firmware upload @connmanager.setIsOTASessionActive(false) @cut_off_time = 10 @dailyMode = 0 @modem_state = Constant::MODEM_REBOOT @continueUpload = 0 end if @gps_state > Constant::GPS_ABORTED && @gps_state < Constant::GPS_FIXED @modem_state = Constant::MODEM_REBOOT @continueUpload = 0 end end elsif event =~%r{modem/uploaderror} Log4Ienso.log.P_NOTICE("uploading error") @modem_state = Constant::MODEM_REBOOT @continueUpload = 0 elsif event =~ %r{camera/firmwareupdate} Log4Ienso.log.P_MAGENTA("------------ NOTE: upgrade firmware request from server ------------\n") @firmwareRemoteRequest = 1 elsif event =~ %r{camera/wifion} Log4Ienso.log.P_NOTICE('Wifi switched on remotely') getDiskSpace @gpstime = Time.now.strftime("%Y-%m-%dT%H:%M:%S") @battery = @comm.get_battery_level() @connmanager.cameraStatusSetandUpdate(@storageused,@storagesize,@battery,@latitude,@longitude,@rssi,@gpstime,@trackingstate,@hotspot, true) enableHotspot elsif event =~ %r{camera/wifioff} Log4Ienso.log.P_NOTICE('WiFi switched off remotely') disableHotspot elsif event =~ %r{menu/field_scan} @set_field_scan_flag=true elsif event =~ %r{menu/refresh} @isMenuDirty = true Log4Ienso.log.P_NOTICE(' menu/refresh -- event received') elsif event =~ %r{camera/deleteall} Log4Ienso.log.P_NOTICE(' delete all -- event received') deleteallMediaFiles elsif event =~ %r{camera/takepic} Log4Ienso.log.P_NOTICE("SMS triggered / profile changed photo request") @continueUpload = 1 @connmanager.setNextPhotoAvailable(true) @overridePhotoUploadBlock = true #changes mode to enable uploading photos $gps_wakeup_flag = true #ensure photo is uploaded #if((@mutex_sleep != nil)&&( @mutex_sleep.try_lock == true) && (@hotspot == 0) && ( check_photo_mode == true)) if((@hotspot == 0)) #&& ( check_photo_mode == true)) #@wq_cap.enqueue_p(method(:take_picture)) start_picture_video(false , nil) else Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} Event camera/takepic ignored because hotspot on or not in photo mode") end #@mutex_sleep.unlock elsif event =~ %r{menu/time_ofoperation} puts("---------------------- menu/time_ofoperation ------ event listener #{data}") packet=[0x0d, data[:days_id], data[:blk_id], data[:off_on], data[:hr], data[:min] ] puts("------------------ control file packet =#{packet}") ret=@comm.set_m0_time_zone(packet) elsif event =~ %r{menu/pir_mode} puts("---------------------- menu/pir_mode ------ event listener #{data}") set_pir_mode() elsif event =~ %r{comm/initial} puts("---------------------- comm/initial ------ event listener #{data}") initial_M0() elsif event =~ %r{system/changecutofftime} Log4Ienso.log.P_YELLOW('cutoff time change event received') encodingtime = data[:extntime] Log4Ienso.log.P_YELLOW("Encoding time is #{encodingtime}") if @mutex_env.synchronize{@env.get_env_value('capture_mode')} == "video" @cut_off_time = @cut_off_time + encodingtime.to_i #(@mutex_env.synchronize{@env.get_env_value('movie_length')}).to_i Log4Ienso.log.P_YELLOW('cut off time changed') end end end def increment_fake_pmic_pir_cntr() @fake_pmic_pir_cntr += 1 #@env.save_env_val('fake_pmic_pir_cntr', @fake_pmic_pir_cntr.to_s) end def increment_fake_pir_cntr() @fake_pir_cntr += 1 #@env.save_env_val('fake_pir_cntr', @fake_pir_cntr.to_s) end def increment_nfake_pir_cntr() @nfake_pir_cntr += 1 #@env.save_env_val('nfake_pir_cntr', @nfake_pir_cntr.to_s) end def power_res() #@connmanager.shutDownOrRebootModem #sleep (0.5) @comm.lte_off() if @comm != nil sleep(4) @power_reset_cntr += 1 @env.save_env_val('reset_cntr', @power_reset_cntr.to_s) Log4Ienso.log.P_ERR("=================== @power_reset_cntr=#{@power_reset_cntr } ======") `rm -rf /dev/ttyUSB*` #clear the usb ports if any sleep (0.3) `rm /dev/ppp` sleep (0.3) `rm /etc/ppp/connect-errors` sleep (0.3) `touch /etc/ppp/connect-errors` sleep(2) @comm.power_off_on() if @comm != nil sleep (5) end def read_final_delay() path = "/media/photos/" + Constant::FINAL_TEST_FILE_NAME fi=File.open(path, "r") fi.each do |line| delay=line.split("Delay=") if delay[1] != nil @delay_default = delay[1].to_i Log4Ienso.log.P_NOTICE("????????????????? delay final=#{@delay_default}") @comm.set_picdelaytime(delay[1]) end end fi.close end def chk_final_test_sw() if($final_test_flag || $final_test_finished_flag) return end path = "/media/photos/" + Constant::FINAL_TEST_FILE_NAME file = Dir[path] if(file.size == 0) Log4Ienso.log.P_NOTICE("????????????????? file is not there") else $final_test_flag = true $final_test_start_time = Time.now @timer_lcd_off.start(false, 'never') disable_heart_bit() read_final_delay() #@comm.interrupt_mask(true) if @comm != nil if ( ($imei != nil) && ($iccid != nil) ) $imei_iccid_valid = true Log4Ienso.log.P_NOTICE("///////// In chk_final_test_sw imei=#{$imei} and iccid=#{$iccid}") end Log4Ienso.log.P_YELLOW( "=============== Final Test file is in sdcard so start the final test routine=======\n") end end # used by Bushnell for testing only def chk_test_server_enabled if $testserver != nil #check end path = "/media/photos/" + Constant::TEST_SERVER_FILE if File.exist?(path) Log4Ienso.log.P_NOTICE("Pointing to test server") data = `cat #{path}` dt = data.split(";") prodserver = "https://wirelesstrophycam.com:8001" if dt[2] != nil $imei = dt[0] $iccid = dt[1] $testserver = dt[2].chomp.strip end if prodserver == $testserver Log4Ienso.log.P_NOTICE("Illegal assignment to Prod server, setting back to default dev server") $testserver ="https://test2.wirelesstrophycam.com:8001" end Log4Ienso.log.P_NOTICE("Pointing to test server #{$imei} #{$iccid} #{$testserver}") else Log4Ienso.log.P_NOTICE("--- Pointing to default server ---") $testserver = nil end end def start_picture_video(resume =false, reason) if(check_photo_mode) Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} ================== @wq_cap.enqueue_p(method(:take_picture) resume=#{resume} ") take_picture_task(resume) sleep(0.01) cameera_set_change(reason) if reason != nil else cameera_set_change(reason) if reason != nil @wq_cap.enqueue_p(method(:take_video), true) Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} ================== @wq_cap.enqueue_p(method(:take_video) before join") $video_recording = true @modemstarttime = Time.now end end # This method handles key press events from the keypad. # # params: # # - code: The keycode of the key that was pressed. See Keypad for details. def pir_detected(data = nil) #if((@mutex_sleep != nil)&&( @mutex_sleep.try_lock == true) && (@hotspot == 0) && (@menu_test_image == 0) && (@otaupload != true) && (@modem_state != Constant::MODEM_REBOOT) ) if((@mutex_sleep != nil)&&( @mutex_sleep.try_lock == true) && (@hotspot == 0) && (@menu_test_image == 0) && (@otaupload != true) ) if (($is_ffmeg_started == true) && !check_photo_mode ) Log4Ienso.log.P_YELLOW("#{Time.now.strftime("%H:%M:%S.%L")} Event pir_detected comm/interrupt ignored because of FFMPEG IS RUNNING") @comm.send_vid_pic_end( ) if @comm != nil else start_picture_video(false , data) end else Log4Ienso.log.P_ERR("#{Time.now.strftime("%H:%M:%S.%L")} @modem_state=#{@modem_state} Warning: Event pir_detected comm/interrupt ignored because of mutex_sleep could not be locked") @comm.send_vid_pic_end( ) if @comm != nil end @mutex_sleep.unlock end def send_thumb_to_server(thumb) if(@mutex_env.synchronize{@env.get_env('wirless_on/off')} == 'on') @picuploadcontrol.lock @photoThreadCount+=1 @picuploadcontrol.unlock exit_code = 1 exit_code = @connmanager.uploadThumb(thumb) if(exit_code == 0) Log4Ienso.log.P_CLEAN("#{Time.now.strftime("%H:%M:%S.%L")} Thumbnail picture send to server #{thumb} #{@photoThreadCount}") @picuploadcontrol.lock @upload_photo_count +=1 #updatePhotoUploadCount @picuploadcontrol.unlock end @picman.submit_thumb(thumb, exit_code) @picuploadcontrol.lock @photoThreadCount-=1 @picuploadcontrol.unlock #f = `free -m | head -2 | tail -1 | tr -s ' '` Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} T #{@photoThreadCount} ") sleep 0.1 Thread.pass end end def take_picture_task( isresume = false, num = @mutex_env.synchronize{@env.get_env_value('capture_count')}) @wq_cap.enqueue_p(method(:take_picture), isresume, 1) @remaining_pictures_no = num -1 if(@remaining_pictures_no > 0) @take_picture_in_process = true @timer_picture_burst.start(false,Constant::PICTURE_BURST_TIME) Log4Ienso.log.P_INFO("Taking several picture Started and @take_picture_in_process=#{@take_picture_in_process} and remaining number is #{@remaining_pictures_no}") else @take_picture_in_process = false end end def count_pir_final_test() @final_test_pir_cntr += 1 Log4Ienso.log.P_YELLOW("\n#{Time.now.strftime("%H:%M:%S.%L")} final test number of pir=#{@final_test_pir_cntr}\n") `i2cset -y 1 0x36 0x10 0x1F` th = Thread.new{ sleep 0.5 `i2cset -y 1 0x36 0x10 0x00` } end def take_picture(isresume = false, num = @mutex_env.synchronize{@env.get_env_value('capture_count')}, filter = nil) Log4Ienso.log.P_YELLOW("\n#{Time.now.strftime("%H:%M:%S.%L")} -------------------------take pic start!!! resume=#{isresume}. #{Thread.current.object_id}\n") begin if @awake_send_vid_pic_end_flag @comm.send_vid_pic_end() if @comm != nil end #@send_vid_pic_end_flag = true #if(@mutex_env.synchronize{@env.get_env_value('imaage_interval')} <= Constant::SLEEP_GUARD_TIME) @timer_sleep_guard.start(false,Constant::SLEEP_GUARD_TIME) #end if(isresume) id = @camera.get_resume_take_pic(num) else id = @camera.capture_image(num, filter) if !@fake_pir_flag end Log4Ienso.log.P_YELLOW("\n#{Time.now.strftime("%H:%M:%S.%L")} -------------------------take pic end !!!#{Thread.current.object_id}\n") if !@fake_pir_flag @thread_save_pic = Thread.new { Log4Ienso.log.P_MAGENTA("\n#{Time.now.strftime("%H:%M:%S.%L")} -------------------------start thread save picture !!!#{Thread.current.object_id}\n") #if @pmic_not_fake_pir # if pir was from pmic do not ask for trigger_pulsed (it's already done) # @pmic_not_fake_pir =false #else # get_trigger_pulse if(!isresume) if get_trigger_pulses() == nil Log4Ienso.log.P_ERR("#{Time.now.strftime("%H:%M:%S.%L")} --------warning: could not fill pir pulse width timing !!!\n") else Log4Ienso.log.P_YELLOW("#{Time.now.strftime("%H:%M:%S.%L")} --------successfuly updated pir pulse width timing !!!\n") end end #end if(@sdcard_status == true) if(@mutex_env.synchronize{@env.get_env('overwrite')} == 'on') numpic_bak = 0 while (@disk_space[:free] <= (@config.picman.min_free_disk)) && @sdcard_status && (@config.picman.min_free_disk < @disk_space[:total]) numpic = @picman.delete_oldest_pic() #system('sync') if(numpic_bak == numpic) break; end #@numpic_bak = numpic Log4Ienso.log.P_INFO("DELETE OLDEST PIC #{numpic}") end end #save_picture(savepath, id) json = makejson() @picman.save_picture(id, json, @mutex_env.synchronize{@env.get_env('wirless_on/off')} == 'on', @camera.get_day_night_state()) if @disk_space[:free] > @config.picman.min_free_disk end Log4Ienso.log.P_MAGENTA("\n#{Time.now.strftime("%H:%M:%S.%L")} -------------------------end thread save picture !!!#{Thread.current.object_id}\n") } else Log4Ienso.log.P_ERR("\n#{Time.now.strftime("%H:%M:%S.%L")} pir was fake so not save it\n") @fake_pir_flag = false end rescue Exception => e Log4Ienso.log.P_ERR("Exception: #{e}") @log.error("Exception: #{e}") end Log4Ienso.log.P_YELLOW("\n#{Time.now.strftime("%H:%M:%S.%L")} -------------------------end of take_ picture !!!#{Thread.current.object_id}\n") #@comm.send_vid_pic_end() if @comm != nil end #update signal strength leds def setSignalStrengthLeds() if @trackingstate == 1 Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} Tracking mode is on so do not turn on LEDs ") return end r=0 r = @rssi #r = r.to_i `i2cset -y 1 0x36 0x10 0x00` if r==0 `i2cset -y 1 0x36 0x10 0x10` if r==1 `i2cset -y 1 0x36 0x10 0x18` if r==2 `i2cset -y 1 0x36 0x10 0x1C` if r==3 `i2cset -y 1 0x36 0x10 0x1E` if r==4 `i2cset -y 1 0x36 0x10 0x1F` if r==5 end def take_video(num) length=@mutex_env.synchronize{@env.get_env_value('movie_length')} Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} =============================== take_video starts, length=#{length} , id=#{Thread.current.object_id} ") begin id=@camera.capture_video(length) if !@fake_pir_flag Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} =============================== take_video after capture_video ") #if(@mutex_env.synchronize{@env.get_env_value('movie_interval') <= Constant::SLEEP_GUARD_TIME) # @timer_sleep_guard.start(false,Constant::SLEEP_GUARD_TIME) #end if(@sdcard_status == true) if(@mutex_env.synchronize{@env.get_env('overwrite')} == 'on') numvid_bak = 0 while (@disk_space[:free] <= (@config.picman.min_free_disk)) && @sdcard_status && (@config.picman.min_free_disk < @disk_space[:total]) numvid = @picman.delete_oldest_vid() if(numvid_bak == numvid) break; end @numvid_bak = numvid Log4Ienso.log.P_INFO("DELETE OLDEST VID #{numvid}") end end #save_picture(savepath, id) json = makejson() frame_rate = 20 hybrid_num = frame_rate * length @picman.save_video(id, json, @mutex_env.synchronize{@env.get_env('movie_resoluition')}, @mutex_env.synchronize{@env.get_env('wirless_on/off')} == 'on', @camera.get_day_night_state(), @mutex_env.synchronize{@env.get_env('hybrid')}, hybrid_num) if @disk_space[:free] > @config.picman.min_free_disk end rescue Exception => e Log4Ienso.log.P_ERR("Exception: #{e}") Log4Ienso.log.P_ERR(e.backtrace) @log.error("Exception: #{e}") @log.error(e.backtrace) end @comm.send_vid_pic_end() if @comm != nil Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} =============================== take_video ends !!! id=#{Thread.current.object_id}") $video_recording = false #@comm.send_vid_pic_end( ) if @comm != nil @timer_lcd_off.start(false, 10) #adding 10 second delay after video is taken end def check_bat_level() @read_bat_counter += 1 if(@read_bat_counter > 50) @read_bat_counter = 0 if ((@view != nil) && (@comm != nil)) level = @comm.get_battery_level() @battery = level @view.set_battery (level) Log4Ienso.log.P_INFO("battery level is [#{level} percent") end end end def take_final_pic() out_path = "/media/photos/" input_path = "/tmp/" cntr = 0 while cntr < 5 do if cntr == 0 dest_pic="Bushnellpicture.jpg" else dest_pic="Bushnellpicture#{cntr}.jpg" end cntr += 1 @view.displayDiret("taking pictures#{cntr}",2, :left) id = @camera.capture_image(1) pic_name = input_path + "#{id}_out_0.jpg" pic = Dir[pic_name] pic.each do |in_filename| out_filename = out_path + dest_pic Log4Ienso.log.P_INFO("In pic file = #{in_filename}") Log4Ienso.log.P_INFO("Out pic file = #{out_filename}") cmd = "cp " + in_filename +" " + out_filename+ " " Log4Ienso.log.P_INFO("command= #{cmd}") system(cmd) system("sync") FileUtils.rm(in_filename) end if cntr == 3 @camera.set_night2 if @camera != nil end sleep(0.050) end @camera.set_day if @camera != nil sleep (0.050) end def change_ir_cut(test) Log4Ienso.log.P_CLEAN("#{Time.now.strftime("%H:%M:%S.%L")} ===================== timer ir_cut timed out") @camera.set_night2() @timer_ir_cut.stop() @timer_ir_cut = nil end def take_final_vid() @view.displayDiret("PLEASE COUNT: ", 1, :left) @view.displayDiret("1-5 LOUDLY :) ", 2, :left) out_path = "/media/photos/" input_path = "/tmp/" dest_vid="BushnellVideo.mp4" @timer_ir_cut = Timer.new('never', method(:change_ir_cut), false) @timer_ir_cut.start(false, 3) Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} ===================== timer ir_cut started") id=@camera.capture_video(5) @camera.set_day() Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} ===================== take_video final test") vid_name = input_path + "#{id}_rec.mpg" vid = Dir[vid_name] vid.each do |in_filename| out_filename = out_path + dest_vid Log4Ienso.log.P_INFO("In vid file = #{in_filename}") Log4Ienso.log.P_INFO("Out vid file = #{out_filename}") cmd = "cp " + in_filename +" " + out_filename+ " " Log4Ienso.log.P_INFO("command= #{cmd}") system(cmd) system("sync") FileUtils.rm(in_filename) end end def final_test() if( ($imei == nil) || ($iccid == nil) ) return end str_out=str_out1=str_out2=nil begin $imei_iccid_valid = true Log4Ienso.log.P_NOTICE("///////// In final_test imei=#{$imei} and iccid=#{$iccid}") version = $firmware_ver #@version.get_version() str = $imei[-5..-1] + " " + $iccid[-7..-1] str2 = version.rjust(7); str3 = $version_m0.rjust(7); str4 = str2[-7..-1] +" "+str3[-7..-1] @view.displayDiret(str, 1, :left) @view.displayDiret(str4, 2, :left) #write to file IMEI.txt out_path = "/media/photos/" dest_imei = out_path + "ICCIDIMEI.txt" dest_vid = out_path + "BushnellVideo.mp4" dest_pic = out_path + "Bushnellpicture.jpg" File.delete(dest_imei) if File.exist?(dest_imei) File.delete(dest_vid) if File.exist?(dest_vid) File.delete(dest_pic) if File.exist?(dest_pic) sleep(0.2) system("sync") vendor = get_vendor() if vendor == nil vendor = $imsi[0..5] if $imsi != nil end str_out = "#{$imei}\n#{$iccid}\n#{version}\n#{$version_m0}\n#{$qtel_firmware}\n#{$qtel_firmware[0..4]}\n#{vendor}\n#{$imsi}\n" Log4Ienso.log.P_NOTICE("///////// In final_test string=#{str_out}") #wait for Enter key to be pressed loop do @keypressed = nil while @keypressed == nil sleep (0.5) end if (@keypressed == 'Enter') if @final_test_start_time == nil pir_time = 0 else pir_time = Time.now - @final_test_start_time end tf = (pir_time.to_i).to_f / @final_test_pir_cntr.to_f tf = tf.round(2) str_out1 = "PIR=#{@final_test_pir_cntr} , #{pir_time.to_i} , #{@delay_default}, #{tf}\n" Log4Ienso.log.P_YELLOW("///////// In final_test we had #{str_out1}\n") break else next end end @connmanager.turn_on_radio() @view.displayDiret("WAITING FOR: ", 1, :left) @view.displayDiret(" 2 seconds...", 2, :left) sleep(1) @view.displayDiret(" 1 seconds...", 2, :left) sleep(1) @view.displayDiret(" 0 seconds...", 2, :left) sleep (0.2) str_out2=str_out + str_out1 File.open(dest_imei, 'w') {|f| f.write(str_out2) } if(check_photo_mode) @camera.set_image_vid_resolution('video') sleep(0.1) take_final_vid() @camera.set_image_vid_resolution('image') take_final_pic() else take_final_vid() sleep(0.1) @camera.set_image_vid_resolution('image') sleep(0.1) take_final_pic() @camera.set_image_vid_resolution('video') end @connmanager.turn_off_radio() #$final_test_flag = false #$imei_iccid_valid = false $final_test_finished_flag = true Log4Ienso.log.P_NOTICE("<<<<<<<<<<<<<>>>>>>>>>>>>...") #@view.displayDiret("FINAL TEST ENDED", 1, :left) #@view.displayDiret("SUCCESSFULLY....", 2, :left) str[6..7] = "!!" @view.displayDiret(str, 1, :left) @view.displayDiret(str4, 2, :left) while true sleep(1) end rescue Exception=>e Log4Ienso.log.P_INFO ("Failed in final_test function err=#{e.backtrace}") Log4Ienso.log.P_NOTICE("//////// Failed in final_test function err=#{e.backtrace}") end end def get_vendor() name = nil if $imsi == nil return nil end pvd = @config.def_env.provider mcc = $imsi[0..2] puts "mcc = #{mcc}" if pvd[mcc] != nil country = pvd[mcc]['country'] digits = pvd[mcc]['mnc_digits'] puts "country=#{country } and no of digits=#{digits}" mnc = $imsi[3..(3+digits-1)] if pvd[mcc]['providers'][mnc]['name'] != nil name = pvd[mcc]['providers'][mnc]['name'] end else puts "MCC=#{mcc} ,this MCC (Mobile Country Code) is not listed " end return name end def check_photo_mode ret = false cap_mode = @mutex_env.synchronize{@env.get_env_value('capture_mode')} if(cap_mode == 'image') ret = true end ret end def get_interval_no(str) ret=@mutex_env.synchronize{@env.get_selected_idx(str) } if(ret == 0) ret = 1 elsif(ret < 4) ret=ret * 5 elsif(ret == 4) ret = 30 else ret = 60 end ret end def get_hr_min(str1) str=@mutex_env.synchronize{@env.get_env_value(str1)} hr1 = get_int_val(str[0].to_i,str[1].to_i) min1= get_int_val(str[3].to_i,str[4].to_i) hr_bcd = int_to_bcd_bytes(hr1) min_bcd = int_to_bcd_bytes(min1) ret=[hr_bcd, min_bcd] end def get_int_val(no1, no2) ret=no1 *10 + no2 end def set_field_scan() ret=@comm.set_m0_rtc() i1=@mutex_env.synchronize{@env.get_selected_idx('field_scan')} i2=get_interval_no('interval_a') hr_min_1= get_hr_min('start_time_a') hr_min_2= get_hr_min('end_time_a') packet=[0x09, 0x00, i1 & 0xff, hr_min_1[0] & 0xff, hr_min_1[1] & 0xff, i2 & 0xff, hr_min_2[0] & 0xff, hr_min_2[1] & 0xff] ret=@comm.set_m0_field_scan(packet) i2=get_interval_no('interval_b') hr_min_1= get_hr_min('start_time_b') hr_min_2= get_hr_min('end_time_b') packet=[0x09, 0x01, i1 & 0xff, hr_min_1[0] & 0xff, hr_min_1[1] & 0xff, i2 & 0xff, hr_min_2[0] & 0xff, hr_min_2[1] & 0xff ] ret=@comm.set_m0_field_scan(packet) @set_field_scan_flag=false end def get_hr_min_too(days_idx) str=@mutex_env.synchronize{@env.get_env('time_ofoperation.time')} str1=str[days_idx] if str != nil str1=str1.split('/') ret = [] str1.each do | time | hr = get_int_val(time[0].to_i,time[1].to_i) min = get_int_val(time[3].to_i,time[4].to_i) ret.push(hr, min) end puts("=========== get_hr_min_too return=#{ret}") ret end def get_offon_too(days_idx) str=@mutex_env.synchronize{@env.get_env('time_ofoperation.off_on')} str1=str[days_idx] if str != nil str1=str1.split('/') ret = 0 power=1 str1.each do | offon | if (offon == '1' ) ret += power end power *=2 end puts("=========== get_offon_too return=#{ret}") ret end def deleteallMediaFiles system("rm -rf /media/photos/DCIM/*") #TODO we should change it later system("rm -rf /media/photos/thumb/*") #TODO we should change it later system("sync") @picman.get_num_photos() if @picman != nil @picman.get_num_videos() if @picman != nil @picman.get_num_photos_videos() if @picman != nil end def int_to_bcd_bytes(int) h10 = ((int / 10) & 0x0f) << 4 h1 = (int % 10) & 0x0f hr = h10 | h1 hr end def turn_on_display() begin Log4Ienso.log.P_YELLOW("#{Time.now.strftime("%H:%M:%S.%L")} [turn_on_display()] Before sync\n") system("sync") Log4Ienso.log.P_YELLOW("#{Time.now.strftime("%H:%M:%S.%L")} [turn_on_display()] After sync\n") if($video_recording == true) @timer_lcd_off.start(false, 'never') else @timer_lcd_off.start(false, @mutex_env.synchronize{@env.get_env_value('lcd_off_time')}) end if (@view.displayOn? == false) @read_bat_counter = 100 check_bat_level() setSignalStrengthLeds() #switch on LED @view.displayOn() #@comm.ignore_pir() if @comm != nil end rescue=>e Log4Ienso.log.P_NOTICE("cannot swtich on display due to env error #{e}") end end # --------- read_power_key() --------------------------------------------------------------------------- # --------- return 0 if no power button pressed or 8/16 in the case of key pressed #---------- return nil in the case of error ---------------------------------------------------------- def read_input(fd, time=0.010) begin Timeout::timeout(time){ line = fd.gets #Log4Ienso.log.P_CLEAN ("#{Time.now.strftime("%H:%M:%S.%L")} #{line.dump} has read from FILE") if line != nil return line } rescue Timeout::Error => e Log4Ienso.log.P_ERR("READ FILE Timeout !!!") return nil end end def read_power_key() begin fd = '/sys/devices/platform/axp81x_board/axp81x_reg' File.open(fd,'r+') { |file| file.puts '4c' line = read_input(file) return nil if line == nil input = line.split('[4c]=') if input[1] == nil return nil end number = input [1].to_i file.puts '4cFF' if number != 0 return number } rescue EOFError => e Log4Ienso.log.P_ERR("EOFError:#{e}") return nil rescue => e Log4Ienso.log.P_ERR("Warning:#{e}") return nil end end def chk_power_key(keyno) if @view != nil if ((keyno & 0x8) == 0x8 || (keyno & 0x10) == 0x10) turn_on_display() if ((keyno & 0x8) == 0x8) Log4Ienso.log.P_ERR(" --------------- long power key=#{keyno}") @comm.a83_sleeping() if @comm != nil @view.displayDiret("POWER DOWN ?", 1, :left) @view.displayDiret("HIT OK TO CONT.", 2, :left) @view.pwr_shut_down(true) else #puts(" --------------- short power key") @view.pwr_shut_down(false) end @view.view_update() end end end def is_int_square? n Math.sqrt(n).to_i == Math.sqrt(n) end def is_fibo? n is_int_square?(5 * n**2 + 4) || is_int_square?(5 * n**2 - 4) end def isEvenTens? n x = n % 10 if x == 0 y = n/10 if y.even? return true else return false end else return false end end def getDiskSpace @storageused = @disk_space[:total] - @disk_space[:free] @storagesize = @disk_space[:total] end def updateShutterSpeed Log4Ienso.log.P_NOTICE("########### shutterspeed changed") refreshMenu @camera.refreshEnv(get_env) # This parameter is only valid for night photos. Daytime is always 'high' and is managed in the Camera class. if(@camera.get_day_night_state() == 'N') @camera.set_shutter_speed(@mutex_env.synchronize{@env.get_env_value('shutter_speed')}) else @camera.set_shutter_speed('high') end end def updateCameraName Log4Ienso.log.P_NOTICE("########### camera name changed") refreshMenu send_camera_name() end def updateImageResolution #if(check_photo_mode) Log4Ienso.log.P_NOTICE("########### imgresolution and pic format changed #{@mutex_env.synchronize{@env.get_env_value('pic_format')}} check_photo_mode #{check_photo_mode}") refreshMenu @camera.refreshEnv(get_env) if(check_photo_mode) @camera.set_resolution(@mutex_env.synchronize{@env.get_env_value('image_resoluition')}) end #end end def updateMovieResolution #if(check_photo_mode == false) Log4Ienso.log.P_NOTICE("########### movieresolution changed , check_photo_mode #{check_photo_mode}") refreshMenu @camera.refreshEnv(get_env) if(!check_photo_mode) @camera.set_resolution_video(@mutex_env.synchronize{@env.get_env_value('movie_resoluition')}) end #end end def updateMovieLength #if(check_photo_mode == false) Log4Ienso.log.P_NOTICE("######camera##### movielength changed check_photo_mode #{check_photo_mode}") refreshMenu @camera.refreshEnv(get_env) @comm.set_image_type(@mutex_env.synchronize{@env.get_env_value('capture_mode')}, @mutex_env.synchronize{@env.get_env_value('movie_length')}) #end end def updatePirDelay #image interval Log4Ienso.log.P_NOTICE("########### pirdelay changed ") refreshMenu @camera.refreshEnv(get_env) @comm.set_picdelaytime(@mutex_env.synchronize{@env.get_env_value('imaage_interval')}) end def updatePIRSensitivity Log4Ienso.log.P_NOTICE("########### PIRSensitivity changed ") refreshMenu @comm.set_pir_sensitivity(@mutex_env.synchronize{@env.get_selected_idx('pir')}) if @comm != nil end def updateledIntensity Log4Ienso.log.P_NOTICE("########### ledintensity changed ") refreshMenu @camera.refreshEnv(get_env) camera_change_ir_led() end def updateTimeStamp Log4Ienso.log.P_NOTICE("########### showtimestamp changed ") refreshMenu @camera.refreshEnv(get_env) @camera.set_image_banner(@mutex_env.synchronize{@env.get_env_value('show_timestamp')}) end def updateCaptureMode Log4Ienso.log.P_NOTICE("########### capturemode changed ") refreshMenu @camera.refreshEnv(get_env) set_image_type(); @camera.set_frame_rate( ) end def updatePirMode Log4Ienso.log.P_NOTICE("########### pirmode changed ") refreshMenu @camera.refreshEnv(get_env) set_pir_mode() set_m0_time_zone() end def updateFieldScan Log4Ienso.log.P_NOTICE("########### fieldscan changed ") refreshMenu @camera.refreshEnv(get_env) set_field_scan() end def updateTimeOfOperation Log4Ienso.log.P_NOTICE("########### timeofoperation changed ") refreshMenu @camera.refreshEnv(get_env) set_m0_time_zone() end def updateTracking Log4Ienso.log.P_NOTICE("########### tracking changed ") refreshMenu end def getNetworkMetrics return @cut_off_time_counter.to_s+"-"+@wakeupcounter.to_s; end def get_trigger_pulses() ret = nil return nil if @comm == nil ret = @comm.get_t1() return nil if ret == nil @t1_pulse = ret ret = @comm.get_t2() return nil if ret == nil @t2_pulse = ret ret = @comm.get_t3() return nil if ret == nil @t3_pulse = ret return true end def sleep_control( param = nil) #sleep_counter_func() if($final_test_flag) final_test() end if( (@timer_lcd_off.stop?) && ($final_test_flag == false) ) @view.displayOff() #@comm.resume_pir() if @comm != nil else check_bat_level() if(@update_view_flag) @view.view_update() end end if @isMenuDirty == true # menu config values have changed from the website Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} Menu needs refresh...") refreshMenu updateCameraName if($developer_mode) @view.displayDiret("DEVELOPER OPTION", 1, :left) @view.displayDiret("ENABLED... ", 2, :left) Log4Ienso.log.P_NOTICE(' keypad/developer_mode -- event received') sleep(2) end @isMenuDirty = false #else #Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} menu is not dirty") end if((@timer_lcd_off.stop?)&&(@timer_sleep_guard.stop?) && ( ! @take_picture_in_process) && (!$final_test_flag) && ($pir_confirmation_flag == false) && (@modem_state == Constant::MODEM_IDLE || @modem_state== Constant::MODEM_OFF || @modem_state == Constant::MODEM_REBOOT) && (@wq_cap.cur_tasks == 0)&&(@wq_send.cur_tasks == 0) && (@hotspot == 0) && ($video_recording == false) && (@gps_state == Constant::GPS_FIXED || @gps_state == Constant::GPS_ABORTED || @gps_state == Constant::GPS_SWITCHED_OFF) && @dailyMode == 0) @mutex_sleep.lock @comm.a83_sleeping() if @comm != nil @comm.interrupt_mask(true) Log4Ienso.log.P_ERR("#{Time.now.strftime("%H:%M:%S.%L")} ----warning------- Entered sleeping process and interrupt masked") #@boot0.clear #if( (@timer_lcd_off.stop?) && ($final_test_flag == false) ) if ($final_test_flag == false) @view.displayOff() #@comm.resume_pir() if @comm != nil end str1 = "#{Time.now.strftime("%H:%M:%S.%L")} #{@sleep_con_check} going to sleep tasks=#{@wq_cap.cur_tasks}," str2 = "#{@wq_send.cur_tasks} m_state=#{@modem_state} g_state=#{@gps_state} t_s_guard=#{@timer_sleep_guard.stop?} t_lcd_off=#{@timer_lcd_off.stop?} " str3 = "hotspot=#{@hotspot} p_in_process=#{@take_picture_in_process} " Log4Ienso.log.P_INFO(str1+str2+str3) updatePhotoUploadCount #`umount /media/photos` #`umount /media/sd-mmcblk1p1` #sleep 0.1 #`mount /dev/mmcblk1p1 /media/photos` #`mount /dev/mmcblk1p1 /media/sd-mmcblk1p1` #GC.start #sleep 0.1 #f = `free -m | head -2 | tail -1 | tr -s ' '` #Log4Ienso.log.P_NOTICE("========+++++++++++++++++++=======") #Log4Ienso.log.P_NOTICE("======== Sleep Memory #{f} =======") #Log4Ienso.log.P_NOTICE("========+++++++++++++++++++=======") @sleep_con_check = 0 Log4Ienso.log.P_CLEAN("#{Time.now.strftime("%H:%M:%S.%L")} befor wp_cap join\n") @wq_cap.join Log4Ienso.log.P_CLEAN("#{Time.now.strftime("%H:%M:%S.%L")} after wp_cap join\n") @wq_send.join if @wq_send.join != nil Log4Ienso.log.P_CLEAN("#{Time.now.strftime("%H:%M:%S.%L")} after wp_send join\n") @thread_modem.kill if @thread_modem != nil Log4Ienso.log.P_CLEAN("#{Time.now.strftime("%H:%M:%S.%L")} before thread_photo join\n") @thread_photo.join if @thread_photo != nil Log4Ienso.log.P_CLEAN("#{Time.now.strftime("%H:%M:%S.%L")} after thread_photo join\n") @thread_photo = nil; @thread_gps.kill if @thread_gps != nil @firmwareota_thread.kill if @firmwareota_thread != nil #switch off LCD `i2cset -y 1 0x36 0x10 0x00` if ( @gps_state == Constant::GPS_ABORTED || @modem_state == Constant::MODEM_REBOOT ) @accessgpstate.lock @gps_state = Constant::GPS_SWITCHED_OFF @accessgpstate.unlock @modem_state = Constant::MODEM_OFF #@connmanager.shutdownModem # this will power down the modem end @picman.enter_sleep(true,@modeSDCardRead) if(check_photo_mode) @camera.req_resume_take_pic(1) #@mutex_env.synchronize{@env.get_env_value('capture_count')) else length=@mutex_env.synchronize{@env.get_env_value('movie_length')} Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} ================== @camera.req_resume_take_vid video length=#{length}") @camera.req_resume_take_vid(length) end @camera.set_sleep() if($developer_mode) $developer_mode = false @isMenuDirty = true end if($gps_wakeup_flag or $timechangedcounter !=0 ) $gps_wakeup_flag = false @comm.wakeup_a83_timer(0, 15) if @comm != nil #status=0 no_gps_fix, delay=15 sec. Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} sent a83 wakeup message to wakeup in 15 seconds") end f = `free -m | head -2 | tail -1 | tr -s ' '` Log4Ienso.log.P_NOTICE("========+++++++++++++++++++=======") Log4Ienso.log.P_CLEAN("============== GC stat=#{GC.stat[:heap_live_slots]}=== Memory #{f} ") Log4Ienso.log.P_NOTICE("========+++++++++++++++++++=======") #puts "os count=#{ObjectSpace.count_objects }" c = `ls -l /media/photos/thumb | wc -l` Log4Ienso.log.P_NOTICE("Photos left to upload #{c}") Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} enter suspend") #Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} enter suspend") sleep (0.1) if @reboot_flag @reboot_flag = false Log4Ienso.log.P_ERR("---- REBOOTING EVERY THING---- ") last_res_time = @env.get_env_value('reset_time').to_i if (Time.now.to_i - last_res_time) > 3600 @env.save_env_val('reset_time', Time.now.to_i.to_s) Log4Ienso.log.P_CLEAN("=================== reset_time=#{Time.now.to_s } ======") power_res() else Log4Ienso.log.P_CLEAN("========= warning: last reset time was #{last_res_time} and now is #{Time.now.to_i.to_s} RESET WAS IGNORED ======") end end # Drop caches #system('echo 1 > /proc/sys/vm/drop_caches') system(%Q(echo mem > /sys/power/state)) #--------------------------------------------------------------------------------------------------------------------- !zzZZ --------------------------------------------------------------- #@boot0.set if File.exist?('/dev/ttyUSB3') && $model == "impulse" `rm -rf /dev/ttyUSB3` Log4Ienso.log.P_MAGENTA("#{Time.now.strftime("%H:%M:%S.%L")} ttyUSB3 was there in the waking Up time so remove it") end @view.init_lcd(true) Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} [ Waking Up ]") powerkey = read_power_key() if powerkey == nil Log4Ienso.log.P_ERR(" Error reading power button") powerkey = 0 end # sometimes the USB is not read/write available or the thumbs are zero size if $usbErrorCount > 6 or $cammoduleresecount > 6 $usbErrorCount = 0 #reboot will reset $cammoduleresecount = 0 system('reboot') end if $dstrebootflag == 1 dststate = @env.get_env('dstrebootcheck') if dststate == 0 Log4Ienso.log.P_ERR("REBOOTING FOR DST") @env.save_env_val('dstrebootcheck',1) system('reboot') end end t=Time.now #reset the dst flah in the same month of dst or a fornight before dst if (t.month==2 or t.month == 3 or t.month==10 or t.month == 11 ) and t.day > 14 dststate = @env.get_env('dstrebootcheck') if dststate == 1 @env.save_env_val('dstrebootcheck', 0) end end reason = @comm.check_wakeup_reason (0) if (reason[:pir] == true) @fake_pir_flag = false if ((reason[:field_scan] == false) && (reason[:field_scanb] == false)) increment_nfake_pir_cntr() if get_trigger_pulses() == nil Log4Ienso.log.P_ERR("#{Time.now.strftime("%H:%M:%S.%L")} --------warning: could not fill pir pulse width timing !!!\n") else Log4Ienso.log.P_YELLOW("#{Time.now.strftime("%H:%M:%S.%L")} --------successfuly updated pir pulse width timing !!!\n") end end #if get_trigger_pulses() == nil # Log4Ienso.log.P_ERR("#{Time.now.strftime("%H:%M:%S.%L")} --------warning: could not fill pir pulse width timing !!!\n") #else # Log4Ienso.log.P_YELLOW("#{Time.now.strftime("%H:%M:%S.%L")} - pmic pir-------successfuly updated pir pulse width timing !!!\n") #end #@pmic_not_fake_pir = true else increment_fake_pmic_pir_cntr() if (!reason[:field_scan] && !reason[:field_scanb] && !reason[:photocell] && !reason[:accelerometer] && !reason[:sms] && !reason[:day]&& !reason[:night] ) end Log4Ienso.log.P_YELLOW("====@fake_pmic_pir_cntr=#{@fake_pmic_pir_cntr } AND @fake_pir_cntr=#{@fake_pir_cntr } AND @not_fake_pir_cntr=#{@nfake_pir_cntr }===\n") $rssi = 0 @lastotatime = Time.now if @lastotatime == 0 # on reboot and first wakeup set lastotatime to enable secondary daily wakeup #if(reason[:pir] == true || reason[:field_scan] == true || reason[:field_scanb] == true) && check_photo_mode() # @comm.send_vid_pic_end( ) if @comm != nil # end @camera.set_temp(@comm.get_temp) Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} [wake up] powerkey = #{powerkey} OTA #{@firmwareRemoteRequest}") chk_power_key(powerkey) @modem_state = Constant::MODEM_OFF @startmode = Constant::RESUME_WAKEUP @wakeupcounter += 1 picsms = false @hotspot = 0 @camera.set_wakeup() @photoThreadCount = 0 @battery = @comm.get_battery_level() Log4Ienso.log.P_NOTICE("battery level is [#{@battery} percent") Log4Ienso.log.P_NOTICE("wakeup conter: #{@wakeupcounter} ") ignoreallevents = false sendpicturemode = Constant::SEND_PIC_NOW dailyalertevent = false @cut_off_time = Constant::GPS_DATA_TIME movielen = @mutex_env.synchronize{@env.get_env_value('movie_length')} movielen = movielen.to_i if ( movielen > 45 ) Log4Ienso.log.P_YELLOW("Changing cutofftime due to video of len #{movielen}") @cut_off_time = Constant::LONG_VIDEO_TIME #increase the cutoff time due to long video end ##################################################################################################################################################### # there are 3 communication modes now, daily, never # there are 2 states of the network - wireless on / off which are independent of the communication modes # 'now' is the default mode amd the normal behaviour of the camera # 'daily' mode - no photos or messages with server are exchanged , except on daily alert. However if sms is received the camera will connect to server ONLY # to get messages. Camera can go into theft/tracking mode # 'never' mode - no photos are ever uploaded, only server messages are obtained. SMS will make camera connect to network. Theft mode will work as normal # wireless off - is the same as never mode, it will connect to server on daily alert. However SMS will not trigger network connection # wireless state will take precedence over the communication mode, therefore if wireless if off and mode is never, the wireless off mode will operate. # during the daily alert the following will happen: 1) GPS fix 2) GNSS ephemeral data file download 3) OTA 4) Photot uploads 5) Get config from the server # daily alert wake up can fail - therefore retry mechanism is implemented. There are two different types of retries. One is for photo uploads and other is for OTA. # the photo upload retries are triggered with gps awake trigger at intervals of 15 seconds and continue untill all pictures are uploaded # the OTA retry is implemented on a pir/sms wakeup and happen after a defined time interval (2 hours). The reason it is done like this is to remove conflicts due # to OTA downloads and reboot. Also, OTA is not a regular occurance, but when that happens it will take precedence over photo uploads. ##################################################################################################################################################### if reason[:dailyalert] == true Log4Ienso.log.P_NOTICE("(((((((((((( DAILY ALERT IS TRUE )))))))))))") dailyalertevent = true $dailyAlertTimeUpdate = true end #reset state if user changes state in the midst of a long running daily alert if @env.get_env('activecommstate') == Constant::SEND_PIC_NOW && ( @longPhotoUploadSession == true || @dailyCheckinMode == true) @longPhotoUploadSession = false $gps_wakeup_flag = false @dailyCheckinMode = false Log4Ienso.log.P_NOTICE("reSET COMM MODES ") end if @env.get_env('gps_tracking') == 'on' ignoreallevents = true ignoreallevents = false if reason[:theftmode] == true end if reason[:sms] == true && @env.get_env('wirless_on/off') == 'off' ignoreallevents == true end @modemstarttime = Time.now # a PIR or other trigger should not stop the long daily upload # the following check ensures the long daily upload continues if @longPhotoUploadSession == true noOffPhotos = `ls -l /media/photos/thumb | wc -l` if noOffPhotos.to_i <= 1 @longPhotoUploadSession = false $gps_wakeup_flag = false @env.save_env_val('activecommstate',Constant::SEND_PIC_NOW) #reset active wake up check on boot, comm mode remains the same as set else $gps_wakeup_flag = true end end if dailyalertevent==false && ( @env.get_env('report_interval') == 'daily' || @env.get_env('report_interval') == 'never' || @env.get_env('wirless_on/off') == 'off') @modeSDCardRead = Constant::DONOT_READ_SD_CARD @modeSDCardRead = Constant::READ_SD_CARD if reason[:a83_awake] == true && @longPhotoUploadSession == true #secondary daily wakeup else @modeSDCardRead = Constant::READ_SD_CARD end sendpicturemode = Constant::SEND_PIC_DAILY if @env.get_env('report_interval') == 'daily' sendpicturemode = Constant::SEND_PIC_NEVER if @env.get_env('report_interval') == 'never' || @env.get_env('wirless_on/off') == 'off' #if wireless is off send photo never == wireless off Log4Ienso.log.P_NOTICE("Pic mode is #{sendpicturemode}") if ( reason[:pir] == false) cameera_set_change(reason) if reason != nil end if ( (reason[:pir] == true || reason[:field_scan] == true || reason[:field_scanb] == true || reason[:sms] == true || reason[:theftmode] == true || dailyalertevent == true || reason[:a83_awake] == true) && (@hotspot == 0) && ignoreallevents == false) @picman.enter_sleep(false,@modeSDCardRead) if(reason[:sms] == false && reason[:a83_awake] == false && dailyalertevent == false) idx = 0 if(reason[:pir] != true) idx =1 end @camera.set_pir_mode(idx) if @camera != nil if(check_photo_mode) @awake_send_vid_pic_end_flag = false end start_picture_video(true, reason) end if(@mutex_env.synchronize{@env.get_env('wirless_on/off')} == 'on' || reason[:sms] == true || reason[:theftmode] == true || dailyalertevent == true || reason[:a83_awake] == true || sendpicturemode == Constant::SEND_PIC_NEVER ) if (reason[:sms] == true) Log4Ienso.log.P_NOTICE("||||| SMS Wake up - received by control application |||||") end if (reason[:theftmode] == true) Log4Ienso.log.P_NOTICE("||||| Theft mode - received by control application |||||") end $menu_values_changed == true if reason[:a83_awake] == true # this ensures the status message is sent along with the status V2 message if sendpicturemode == Constant::SEND_PIC_NOW || ( sendpicturemode > Constant::SEND_PIC_NOW && dailyalertevent == true ) || reason[:sms] == true || reason[:a83_awake] == true || @firmwareRemoteRequest == 1 || ( @dailyCheckinStatus == Constant::FAILED_ONCE && @dailyupdatetimedelta > Constant::FAILED_DAILY_ALERT_RETRYTIME) @thread_modem = Thread.new { startModemandNetwork(@mutex_env.synchronize{@env.get_env_value('Select_Network')}, @starttype) @starttype = Constant::RESUME_WAKEUP if @starttype == Constant::COLD_BOOT } else Log4Ienso.log.P_NOTICE("XXX - NOT STARTING MODEM - XXX") end if reason[:sms] == true count=0 Log4Ienso.log.P_INFO("TESTING IF IT IS A SMS") while @modem_state < Constant::MODEM_PORTS_AVAILABLE Log4Ienso.log.P_INFO("modem state is #{@modem_state}") sleep 1 count+=1 break if count > 10 end if @connmanager.isTakePicSMS Log4Ienso.log.P_NOTICE("||||| SMS is for taking pic |||||") else Log4Ienso.log.P_NOTICE("||||| SMS is for wakeup |||||") end end if (reason[:sms] == true || (reason[:a83_awake] == true && @longPhotoUploadSession == false && @dailyCheckinMode == false) || @firmwareRemoteRequest == 1) if picsms == true Log4Ienso.log.P_NOTICE("||||| sending pic/video asap |||||") @thread_photo = Thread.new { sendPhotos(Constant::UPLOAD_PHOTOS_AND_SERVER_CMDS) } else picsms == false && reason[:sms] == true @thread_photo = Thread.new { sendPhotos(Constant::GET_SERVER_CMDS_ONLY) } end elsif @longPhotoUploadSession == true && reason[:a83_awake] == true Log4Ienso.log.P_NOTICE("||||| SECONDARY DAILY WAKEUP - SENDING PICTURES |||||") noOffPhotos = `ls -l /media/photos/thumb | wc -l` if noOffPhotos.to_i <= 1 @longPhotoUploadSession = false $gps_wakeup_flag = false @env.save_env_val('activecommstate',Constant::SEND_PIC_NOW) #reset active wake up check on boot, comm mode remains the same as set else $gps_wakeup_flag = true Log4Ienso.log.P_NOTICE("XXX - Cut off time is #{@cut_off_time} - XXX") @longPhotoUploadSession = true @thread_photo = Thread.new { sendPhotos(Constant::UPLOAD_PHOTOS_AND_SERVER_CMDS) } end elsif @dailyCheckinMode == true && reason[:a83_awake] == true Log4Ienso.log.P_NOTICE("||||| SECONDARY DAILY CHECKIN |||||") if $serverCMDSRcvd == true Log4Ienso.log.P_NOTICE("||||| SECONDARY DAILY CHECKIN COMPLETE |||||") @dailyCheckinMode = false $gps_wakeup_flag = false $serverCMDSRcvd = false @env.save_env_val('activecommstate',Constant::SEND_PIC_NOW) #reset active wake up check on boot, comm mode remains the same as set else Log4Ienso.log.P_NOTICE("||||| SECONDARY DAILY CHECKIN .. next try |||||") $gps_wakeup_flag = true @dailyCheckinMode = true @thread_photo = Thread.new { sendPhotos(Constant::GET_SERVER_CMDS_ONLY) } end else if sendpicturemode == Constant::SEND_PIC_DAILY && dailyalertevent == true Log4Ienso.log.P_NOTICE("||||| DAILY WAKEUP - Will try GPS + OTA |||||") $gps_wakeup_flag = true @longPhotoUploadSession = true @env.save_env_val('activecommstate',Constant::SEND_PIC_DAILY) elsif sendpicturemode == Constant::SEND_PIC_NEVER && dailyalertevent == true Log4Ienso.log.P_NOTICE("||||| DAILY CHECKIN ONLY |||||") $gps_wakeup_flag = true @dailyCheckinMode = true @env.save_env_val('activecommstate',Constant::SEND_PIC_NEVER) @thread_photo = Thread.new { sendPhotos(Constant::GET_SERVER_CMDS_ONLY) } elsif sendpicturemode == Constant::SEND_PIC_NOW @thread_photo = Thread.new { sendPhotos(Constant::UPLOAD_PHOTOS_AND_SERVER_CMDS) } else Log4Ienso.log.P_INFO("not starting photo upload thread pic mode is: #{sendpicturemode}") @modem_state = Constant::MODEM_IDLE sleep 0.2 end end # if (reason[:dailyalert] == true || @firmwareRemoteRequest == 1) used for testing if (@firmwareRemoteRequest == 1 && @battery.to_i > 50) Log4Ienso.log.P_NOTICE("||||| OTA Update with batt #{@battery} |||||") count = 0 while @modem_state < Constant::MODEM_CONNECTED Log4Ienso.log.P_INFO("modem state is #{@modem_state}") sleep 1 count+=1 break if count > 10 end if @connmanager != nil && @modem_state >= Constant::MODEM_CONNECTED @connmanager.setIsOTASessionActive(true) @firmwareRemoteRequest = 0 @cut_off_time = Constant::OTA_UPDATE_TIME @dailyMode = 1 @firmwareota_thread = Thread.new{ downloadFirmwareOTA(Constant::UPGRADE_OR_DOWNGRADE_FIRMWARE) } end end #refresh GPS data once on wakeup, try for the first three times if @wakeupcounter < 3 && @modem_state > Constant::MODEM_OFF && @gpsxtraupdate == false && reason[:sms] == false if @connmanager != nil @connmanager.updateGPSFromFTP() @gpsxtraupdate = true end end else if @sleep_count < 2 #@sleep_count is used to count wakeup when wireless is off. When wireless is on @wakeupcounter is used. @thread_modem = Thread.new { startModemandNetwork(@mutex_env.synchronize{@env.get_env_value('Select_Network')},Constant::RESUME_WAKEUP) @starttype = Constant::RESUME_WAKEUP if @starttype == Constant::COLD_BOOT } @thread_photo = Thread.new { sendPhotos(Constant::GET_SERVER_CMDS_ONLY) } @modemstarttime = Time.now @sleep_count += 1 end end if(reason[:theftmode] == true) && @starttype != Constant::COLD_BOOT # this mode will trigger every 5 minutes (M0 trigger) until cancelled by the user @mutex_env.synchronize{@env.save_env_val('wirless_on/off','on')} if @mutex_env.synchronize{@env.get_env('wirless_on/off')} == 'off' # swtich on the wireless if it is off @mutex_env.synchronize{@env.save_env_val('capture_mode','image')} if @mutex_env.synchronize{@env.get_env('capture_mode')} == 'video' # change to picture mode @mutex_env.synchronize{ @env.save_env_val('tracking', "on")} @mutex_env.synchronize{ @env.save_env_val('gps_tracking', "on")} @location_available = false # to trigger gps on set location available to off @trackingstate = 1 getDiskSpace @cut_off_time = Constant::THEFT_MODE_TIME @comm.check_theft_mode_on_reboot @gpstime = Time.now.strftime("%Y-%m-%dT%H:%M:%S") @connmanager.cameraStatusSetandUpdate(@storageused,@storagesize,@battery,@latitude,@longitude,@rssi,@gpstime,@trackingstate,@hotspot, true) end @gpstrycounter += 1 validcount = false #validcount = is_fibo? @gpstrycounter # this is better but for power review not good at gps attempts frequent at start validcount = isEvenTens? @gpstrycounter #this will wake up gps on 20,40,60... even tens besides 1st wakeup if @connmanager != nil && ( validcount == true || reason[:theftmode] == true || dailyalertevent == true ) #swtich on GPS based on a fibonacci sequence or if theft mode is true Log4Ienso.log.P_INFO("Starting GPS on #{@gpstrycounter}") @gps_state = Constant::GPS_SWITCHED_OFF @cut_off_time = Constant::NO_GPS_DATA_TIME @thread_gps = Thread.new { getGPSLocation } else if @location_available == true Log4Ienso.log.P_INFO("Have location already, exiting " + @latitude.to_s + " " + @longitude.to_s) else Log4Ienso.log.P_INFO("Still no location on count #{@gpstrycounter}" ) end end @storageused = 0 # only for testing remove in production @dailyCheckinStatus = @env.get_env('dailycheckin') # daily checkin status stored in persistant storage due to reboots after OTA upgrade @dailyupdatetimedelta = Time.now - @lastotatime @env.save_env_val('dailycheckin',0) if @dailyCheckinStatus == Constant::FAILED_TWICE #no more tries #the OTA retry attempts happen indepent of the GPS+GNSS+Photo uploads which happen right after the first dialy alert ( only on failure or if there are a lot of photos ()>50) to be uploaded if ( ( dailyalertevent == true && @trackingstate == 0 ) || ( @dailyCheckinStatus == Constant::FAILED_ONCE && @dailyupdatetimedelta > Constant::FAILED_DAILY_ALERT_RETRYTIME) ) # daily alert will be ignored if the camera is in tracking mode. Log4Ienso.log.P_NOTICE("||||| Daily Alert OTA - received by control application #{@dailyCheckinStatus} |||||") @lastotatime = Time.now count=0 @env.save_env_val('dailycheckin',1) if @dailyCheckinStatus == Constant::FIRST_ATTEMPT_ON_TRIGGER # daily checkin OTA started @env.save_env_val('dailycheckin',2) if @dailyCheckinStatus == Constant::FAILED_ONCE # second OTA attempt while @modem_state < Constant::MODEM_CONNECTED Log4Ienso.log.P_INFO("modem state is #{@modem_state}") sleep 1 count+=1 break if count > 10 end @gpstrycounter = 1 getDiskSpace #@storageused = 999999 # only for testing remove in production @gpsxtraupdate = false # on next wakeup update ephermis data @gpstime = Time.now.strftime("%Y-%m-%dT%H:%M:%S") $trigger = "DAILYALERT" #for server diagnostics @connmanager.cameraStatusSetandUpdate(@storageused,@storagesize,@battery,@latitude,@longitude,@rssi,@gpstime,@trackingstate,@hotspot, true) #while @photoThreadExited != true # sleep 0.5 # Log4Ienso.log.P_INFO("waiting for photos to upload...") #end if @connmanager != nil && @modem_state >= Constant::MODEM_CONNECTED @connmanager.setLocalTime() @connmanager.setIsOTASessionActive(true) #@firmwareRemoteRequest = 0 @cut_off_time = Constant::OTA_UPDATE_TIME if @hotspot == 0 @dailyMode = 1 #@trackingstate=0 @connmanager.updateGPSFromFTP() #getDiskSpace @gpstime = Time.now.strftime("%Y-%m-%dT%H:%M:%S") @connmanager.cameraStatusSetandUpdate(@storageused,@storagesize,@battery,@latitude,@longitude,@rssi,@gpstime,@trackingstate,@hotspot, true) if @battery.to_i > 50 @firmwareota_thread = Thread.new{ downloadFirmwareOTA(Constant::ONLY_UPGRADE_FIRMWARE) } end end end if @wakeupcounter.to_i.even? || ( @updateServer == 1) || reason[:a83_awake] == true @gpstime = Time.now.strftime("%Y-%m-%dT%H:%M:%S") check_bat_level() getDiskSpace #if @storageused != 999999 # only for testing remove if condition in production @updateServer = 0 @gpstime = Time.now.strftime("%Y-%m-%dT%H:%M:%S") @connmanager.cameraStatusSetandUpdate(@storageused,@storagesize,@battery,@latitude,@longitude,@rssi,@gpstime,@trackingstate,@hotspot, true) end if(@mutex_env.synchronize{@env.get_env('lcd_force_on')} == 'on') @timer_lcd_off.start(false, 1) @view.displayOn() end end if $menu_values_changed == true #@trackingstate = 0 getDiskSpace #if @storageused != 999999 # only for testing remove if condition in production @gpstime = Time.now.strftime("%Y-%m-%dT%H:%M:%S") @connmanager.cameraStatusSetandUpdate(@storageused,@storagesize,@battery,@latitude,@longitude,@rssi,@gpstime,@trackingstate,@hotspot, false) end if ( (reason[:power_button] == true) || (reason[:accelerometer] == true) ) # During sleep mode, if user press power button more than 1 sec, PMIC register is not set. So we need below code. @turn_on_display_flag = true end Log4Ienso.log.P_YELLOW("#{Time.now.strftime("%H:%M:%S.%L")} [wake up] M0 interrupt enabled") @comm.interrupt_mask(false) if !@awake_send_vid_pic_end_flag @comm.send_vid_pic_end() if @comm != nil @awake_send_vid_pic_end_flag = true end if $send_end_pic_flag @comm.send_vid_pic_end( ) if @comm != nil $send_end_pic_flag = false end if(@mutex_sleep.locked?) @mutex_sleep.unlock end else #system(%Q(/opt/wtc2.0/src/powerkey.sh)) #powerkey = $?.exitstatus.to_i powerkey = read_power_key() if powerkey == nil Log4Ienso.log.P_ERR(" Error reading power button") powerkey = 0 end chk_power_key(powerkey) @elapsedTime = 0 @sleep_con_check += 1 if (@sleep_con_check > 20) st1 = '' if (!@timer_lcd_off.stop?) then st1 += ' @timer_lcd_off,' end; if (!@timer_sleep_guard.stop?) then st1 += ' @timer_sleep_guard,' end; if (@take_picture_in_process) then st1 += ' take_picture_in_process,' end; if ( $final_test_flag ) then st1 += ' $final_test_flag ,' end; if ( @wq_cap.cur_tasks != 0 ) then st1 += " cur. tasks=#{@wq_cap.cur_tasks} ," end; if ( @wq_send.cur_tasks != 0 ) then st1 += " send tasks=#{@wq_send.cur_tasks} ," end; if ( @hotspot != 0 ) then st1 += ' @hotspot ,' end; if ( $pir_confirmation_flag ) then st1 += ' $pir_confirmation_flag ,' end; if (@modem_state != Constant::MODEM_IDLE && @modem_state != Constant::MODEM_OFF && @modem_state != Constant::MODEM_REBOOT) st1 += " modem_state=#{@modem_state} ," end if (@gps_state != Constant::GPS_FIXED && @gps_state != Constant::GPS_ABORTED && @gps_state != Constant::GPS_SWITCHED_OFF) st1 += " gps_state=#{@gps_state} ," end str1 = "#{Time.now.strftime("%H:%M:%S.%L")} Can't sleep : cut off time: #{@cut_off_time} " Log4Ienso.log.P_INFO(str1+st1) Log4Ienso.log.P_INFO("elapsed time is" + @elapsedTime.to_s) if (@elapsedTime > 0) @sleep_con_check = 0 end if((@timer_picture_burst.stop?) && @take_picture_in_process) take_picture_task( false, @remaining_pictures_no) end if @modemstarttime != nil @elapsedTime = Time.now - @modemstarttime if @elapsedTime > 1000 @modemstarttime = Time.now @elapsedTime = 0 end @modemstarttime = Time.now if ( @elapsedTime < 0 ) #Log4Ienso.log.P_INFO("elapsed time is" + elapsedTime.to_s) @connmanager.SetIsGPSSessionActive(false) if( (@elapsedTime > @cut_off_time ) && ($final_test_flag == false) && ( @modem_state >= Constant::MODEM_CONNECTING || @modem_state == Constant::MODEM_CONNECTED || @modem_state == Constant::MODEM_STARTING_UPLOAD || @modem_state == Constant::MODEM_PORTS_AVAILABLE || @gps_state >= Constant::GPS_STARTED ) && ( @dailyMode == 0 ) ) Log4Ienso.log.P_CLEAN("FORCING modem shutdown...#{@elapsedTime}") if @startmode == Constant::COLD_BOOT && @elapsedTime > 300 # condition happens when modem date switches from 1970 to current time Log4Ienso.log.P_NOTICE("Letting modem to boot up correctly - waiting for another 30 seconds") sleep 30 end updatePhotoUploadCount $video_recording = false $pir_confirmation_flag = false @take_picture_in_process = false @cut_off_time_counter+=1 if @hotspot == 1 disableHotspot end if($gps_wakeup_flag) $gps_wakeup_flag = false @comm.wakeup_a83_timer(0, 15) if @comm != nil #status=0 no_gps_fix, delay=10 sec. Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} sent a83 wakeup message to wakeup in 10 seconds") end @firmwareota_thread.kill if @firmwareota_thread != nil if @gps_state >= Constant::GPS_STARTED @accessgpstate.lock @gps_state = Constant::GPS_ABORTED @accessgpstate.unlock @connmanager.stopGPS() end @connmanager.shutdownModem @modem_state = Constant::MODEM_REBOOT @thread_gps.kill if @thread_gps != nil Log4Ienso.log.P_NOTICE("(sleep_control)FORCING modem shutdown...killed gps thread...#{@gps_state} #{@modem_state} ") @thread_modem.kill if @thread_modem != nil Log4Ienso.log.P_NOTICE("(sleep_control)FORCING modem shutdown...killed modem thread...#{@gps_state} #{@modem_state} ") @thread_photo.kill if @thread_photo != nil Log4Ienso.log.P_NOTICE("(sleep_control)FORCING modem shutdown...killed photo thread...#{@gps_state} #{@modem_state} ") @accessgpstate.lock @gps_state = Constant::GPS_ABORTED @accessgpstate.unlock end #else #@modem_state = Constant::MODEM_IDLE end if(@set_field_scan_flag) set_field_scan() end end if(@turn_on_display_flag) @turn_on_display_flag = false turn_on_display() @view.view_update() end end end #returns true if photo mode options = { } optparse = OptionParser.new{|opt| opt.banner = 'This is the service template' opt.on('-cPATH', '--config=PATH', 'Location of the config file.'){|arg| raise("File #{arg} does not exit.") if not File.exists?(arg) options[:config_path] = arg } } optparse.parse! begin options.assert_keys(:config_path) rescue puts("--config=path must be specified") exit(-1) end begin con = Control.new(YAML.load(File.read(options[:config_path])).to_hashugar) puts "Initial Done" loop{ con.sleep_control() sleep(0.1) con.check_heart_bit() } rescue Exception => e puts("Exception: #{e}") puts(e.backtrace) log = Syslog::Logger.new("wtc2.0") log.fatal("Exception: #{e}") log.fatal(e.backtrace) end opt/wtc2.0/src/README.txt0000644000175200017520000000437613557057144015425 0ustar bushnellbushnell== Introduction The WTC2.0 application comprises multiple processes. The main part of the application is control.rb (Control). This is the main Control and is responsible for all operations. The other processes are responsible for specific, specialized operations and are under the control of control.rb. For example. lcd.rb (LcdScreen) is responsible for driving the LCD screen. == Configuration This application will be used on multiple cameras. Because of this, a configuration file has been create that contains as much platform specific information as possible. The application uses this information to behave accordingly. The configuraiton file is written in YAML[http://yaml.org] and has the following general structure: 1. A global section for information that affect multiple parts of the application 1. Class/subsystem specific sections == Diagram == Control Control is responsible for all application functions. It performs its duties using various other classes and processes. All other classes and processes are subjugated by Control and shall not perform any actions independently, unless required. The Camera Control is responsible for: 1. taking still images 1. taking video captures 1. controlling the IR cut filter 1. controlling the IR LEDs (flash) While performing these tasks, Camera Control also makes determinations about about day and night modes, exposure time, and the flash pulse width. The application has several user interfaces. The UI requirements are the following: 1. Smart phone control (IOS/Android) 1. Web server control 1. LCD user interface control *TODO*: To implement these various interfaces, it is likely best to use the Model-View-Control pattern. This is to be discussed. In addition, a command line interface is also required for debugging, remote control, remote logging, etc. == MQTT Broker Mosquitto is present and running on the camera. Control is reachable at topic 'control'. Also, an MQTT backed ORB has been implemented. See MQTTServer for details. Control methods are accessible via this method. == Web Server (CGI) A web server is present on the camera and can be used as the control interface over WiFi from the smart phone. This still has to be discussed with Zipit. == Wireless Access Point (Wifi AP) == Logging opt/wtc2.0/src/verizon.sh0000755000175200017520000000073413557057144015754 0ustar bushnellbushnell#!/bin/sh if [ -e /dev/ttyUSB3 ] then echo at+qmbncfg=\"select\",\"hVoLTE-Verizon\" sleep 0.3 echo at+cgdcont=1,\"IPV4V6\",\"VZWIMS\","0.0.0.0",0,0,0,0 > /dev/ttyUSB3 sleep 0.3 echo at+cgdcont=2,\"IPV4V6\",\"VZWADMIN\",\"0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0\",0,0,0,0 > /dev/ttyUSB3 sleep 0.3 echo at+cgdcont=3,\"IPV4V6\",\"vzwinternet\",\"0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0\",0,0,0,0 > /dev/ttyUSB3 sleep 0.3 echo at+cgact=1,3 > /dev/ttyUSB3 fi opt/wtc2.0/src/timer.rb0000644000175200017520000000326113557057144015364 0ustar bushnellbushnell require 'thread' class Timer Never = 99999999999999 def initialize(timeOut, cb = nil, param=nil) @cb = cb @param = param @current = 0 @mutex = Mutex.new @stop = 0 conv_timeout(timeOut) @th = Thread.new(){ loop { sleep(0.1) if(@timeOut == Never) next end @mutex.synchronize { if(@stop == 0) @current = @current + 1 end } if(@current >= @timeOut) stop if(@cb != nil) @cb.call(@param) end end } } end def conv_timeout(timeOut) if(timeOut == 'never') @timeOut = Never else @timeOut = timeOut*10 end end def start(now = false, timeOut = nil) @mutex.synchronize { if(timeOut != nil) conv_timeout(timeOut) end if(now == true) @current = @timeOut else @current = 0 end @stop = 0 } end def stop? @stop == 1 end def reset(timeOut = nil) @mutex.synchronize { if(timeOut != nil) conv_timeout(timeOut) end @current = 0 } end def stop @mutex.synchronize { @current = 0 @stop = 1 } end def get_count @timeOut - @current end end # Test code... if $0 == __FILE__ endopt/wtc2.0/src/gpio.rb0000644000175200017520000000340713557057144015204 0ustar bushnellbushnell # This class represents a /sys/class/gpio entry. class Gpio attr_accessor :direction def initialize(port) if(port.kind_of?(String)) @num = (port[1].ord - 'A'.ord) * 32 + port[2..5].to_i else @num = nil end @fd_value = nil @fd_direction = nil @fd_edge = nil if(@num != nil) if not File.exists?("/sys/class/gpio/gpio#{@num}") File.open("/sys/class/gpio/export", 'w'){|f| f.write(@num) } end @fd_value = File.new("/sys/class/gpio/gpio#{@num}/value", File::RDWR) # flush every write. @fd_value.sync = true @fd_direction = File.new("/sys/class/gpio/gpio#{@num}/direction", File::RDWR) # flush every write. @fd_direction.sync = true if File.exists?("/sys/class/gpio/gpio#{@num}/edge") @fd_edge = File.new("/sys/class/gpio/gpio#{@num}/edge", File::RDWR) # flush every write. @fd_edge.sync = true end end end def set value(1) end def clear value(0) end def value(val) if(@fd_value != nil) @fd_value << "#{val}" sleep(0.000001) end end def direction=(dir) if(@fd_direction != nil) @fd_direction.write(dir) end end def direction() if(@fd_direction != nil) @fd_direction.rewind @fd_direction.read end end def get if(@fd_value != nil) @fd_value.rewind @fd_value.read end end def cal_port_num(port) num = port[1] end end opt/wtc2.0/src/disablehotspotetstreaming.sh0000755000175200017520000000025613557057144021546 0ustar bushnellbushnell#!/bin/sh #id="$(ps -ef | awk '/[v]4l2grab/{print $1}')" #kill -9 $id #sleep 1 id="$(ps -ef | awk '/[m]jpg_streamer/{print $1}')" kill -9 $id umount ramfs sleep 1 opt/wtc2.0/src/http_rest_zipit.rb0000644000175200017520000017372313557057144017512 0ustar bushnellbushnell $LOAD_PATH.push File.expand_path("../../lib", __FILE__) require 'rest-client' require 'json' require 'exifr/jpeg' require 'syslog/logger' require 'yaml' require 'utils' require 'optparse' require 'env' require 'debug' # init the class with the imei and iccid of the device class ZipItRestApi COLD_BOOT = 0 RESUME_WAKEUP = 1 # provide the imei, iccid and the providers end point def initialize(imei, iccid, api_end_point,sessionfile,config) # Instance variables begin @imei = imei @iccid = iccid api_end_point = api_end_point.chomp.strip if api_end_point != nil @api_end_point =api_end_point @token = nil @sessionfile = sessionfile @config = config @log = Syslog::Logger.new(@config.control.log_name) @env = Env.new(@config.def_env) @laststatuscode="" @pic_path = "/media/photos/DCIM/" #@config.pic_path @thumb_path = "/media/photos/thumb/" #@config.thumb_path Log4Ienso.log.P_INFO("API end point is >>[#{api_end_point}]<<") rescue Log4Ienso.log.P_INFO("Failed to init the ZIPIT HTTP Obj") end end def getCameraName(id) val = @env.get_env_value(id) return val end def getValue(id) val = @env.get_env_value(id) split_val = val.to_s.split('_') if(split_val[1] != nil) if split_val[1] == "minute" val = split_val[0].to_i * 60 else val = split_val[0] end end Log4Ienso.log.P_INFO("Env value for " + id.to_s + " is " + val.to_s) return val.to_s end def getAllValues(id) val = @env.get_env(id) Log4Ienso.log.P_INFO("Env value for " + id.to_s + " is " + val.to_s) return val.to_s end def setValue(id,value) @env.save_env_val(id,value) Log4Ienso.log.P_INFO("set new value " + value.to_s + " where id is " + id.to_s) end def getEnvValues() @env = Env.new(@config.def_env) if $lastupdatetime == nil $lastupdatetime = Time.now.strftime("%Y-%m-%dT%H:%M:%S") end Log4Ienso.log.P_INFO("Started getting env values...#{$lastupdatetime}" ) @env_cameraname = getCameraName('camera_name') @env_wireless = getValue('wirless_on/off') @env_wireless = "true" if @env_wireless == "on" @env_wireless = "false" if @env_wireless == "off" @env_reportinterval = getValue('report_interval') @env_reportinterval = "quick" if @env_reportinterval == "now" @env_overwrite = getValue('overwrite') @env_overwrite = "true" if @env_overwrite == "on" @env_overwrite = "false" if @env_overwrite == "off" @env_capturemode = getValue('capture_mode') @env_capturemode = "i" if @env_capturemode == 'image' @env_capturemode = "m" if @env_capturemode == 'video' @env_hybrid = getValue('hybrid') if @env_hybrid == 'on' # i,m,h on server, on camera h stored seprately @env_capturemode ='h' end @env_capturecount = getValue('capture_count') @env_shutterspeed = getValue('shutter_speed') @env_shutterspeed = "medium" if @env_shutterspeed == "med" @env_imageresolution = getValue('image_resoluition') @env_imageresolution = "99" if @env_imageresolution == "20" @env_imageresolution = "3" if @env_imageresolution == "2" @env_movieresolution = getValue('movie_resoluition') @env_movieresolution = "640" if @env_movieresolution == "640x480" @env_movieresolution = "720" if @env_movieresolution == "720p30" @env_movieresolution = "1080" if @env_movieresolution == "1080p30" @env_movielength = getValue('movie_length') @env_movieinterval = getValue('movie_interval') @env_pirdelay = getValue('imaage_interval') @env_pirsensitivity = getValue('pir') #@env_pirsenstivity = getValue('camera_name') @env_ledintensity = getValue('led_power') @env_ledintensity="medium" if @env_ledintensity == "med" @env_picformat = getValue('pic_format') @env_picformat="0" if @env_picformat=="3to2" @env_picformat="1" if @env_picformat=="16to9" @env_showtimestamp = getValue('show_timestamp') @env_showtimestamp = "true" if @env_showtimestamp == "on" @env_showtimestamp = "false" if @env_showtimestamp == "off" @env_fieldscan = getValue('field_scan') @env_fieldscan = "true" if @env_fieldscan == "on" @env_fieldscan = "false" if @env_fieldscan == "off" @env_scan_ab = getValue('scan_ab') @env_interval_a = getValue('interval_a') @env_interval_b = getValue('interval_b') @env_tracking = getValue('tracking') @env_scan1start = getValue('start_time_a') if @env_scan1start.length == 5 @env_scan1start = @env_scan1start + ":00" # server needs secodns else @env_scan1start = "00:00:00" end @env_scan1end = getValue('end_time_a') if @env_scan1end.length == 5 @env_scan1end = @env_scan1end + ":00" # server needs secodns else @env_scan1end = "00:00:00" end @env_scan2start = getValue('start_time_b') if @env_scan2start.length == 5 @env_scan2start = @env_scan2start + ":00" # server needs secodns else @env_scan2start = "00:00:00" end @env_scan2end = getValue('end_time_b') if @env_scan2end.length == 5 @env_scan2end = @env_scan2end + ":00" # server needs secodns else @env_scan2end = "00:00:00" end @env_embedgps = getValue('embedded_gps') @env_embedgps = "true" if @env_embedgps == "on" @env_embedgps = "false" if @env_embedgps == "off" @env_diagnostics = getValue('diagnostics') @env_gpstracking = getValue('gps_tracking') @env_gpson_off = getValue('switch_on/off_gps') @env_pirmode = getValue('pir_mode') @env_pir = getValue('pir') #sensitivity Log4Ienso.log.P_INFO("Complted getting new env values..." ) #time of operation @env_top_state = getAllValues('time_ofoperation.enable') @env_top_days = getAllValues('time_ofoperation.days') onoffstate = getAllValues('time_ofoperation.off_on') toptime = getAllValues('time_ofoperation.time') onoffstate = onoffstate.split(",").map(&:to_s) t = onoffstate[0] t=t.tr("[","") t=t.tr("\"","") #puts(t) @mf_camera = t.split("/").map(&:to_i) t = onoffstate[1] t=t.tr("[","") t=t.tr("\"","") @sat_camera = t.split("/").map(&:to_i) t = onoffstate[2] t=t.tr("[","") t=t.tr("\"","") @sun_camera = t.split("/").map(&:to_i) toptime = toptime.split(",").map(&:to_s) t = toptime[0].gsub("\"", "").gsub("[", "") @mf_period = t.split("/").map(&:to_s) t = toptime[1].gsub("\"", "") @sat_period = t.split("/").map(&:to_s) t = toptime[2].gsub("\"", "").gsub("]", "") @sun_period = t.split("/").map(&:to_s) puts(@mf_camera) puts("-------") puts(@sat_camera) puts("________") puts(@sun_camera) puts("##################") puts(@mf_period) puts("-------") puts(@sat_period) puts("________") puts(@sun_period) Log4Ienso.log.P_INFO("Complted getting env values..." ) end #the zipit api is token based. The register step is the first #needed for every session to obtain a valid token # the token expires every 1500 minutes /25 hour # and the time may change in the future #therefore just keeping the token per session of 1/2 hour def register validtoken=0 begin if File.exist?(@sessionfile) filemodtime=(Time.now - File.stat(@sessionfile).mtime).to_i.abs / 60 Log4Ienso.log.P_INFO("Session file time is " + filemodtime.to_s + " min") if filemodtime < 10 #changing session to 10 min because 30 min on test server @token = `cat #{@sessionfile} | head -1` @token =@token.chomp Log4Ienso.log.P_INFO("got token from file") if @token!='' validtoken = 1 end end end rescue Exception=>e @laststatuscode = e.to_s Log4Ienso.log.P_INFO("exception in register " + e.to_s ) end if validtoken == 0 begin response = RestClient.post(@api_end_point+"/Device/Register", {"imei" => @imei, "iccid" => @iccid}, {:accept => :json}) rescue Exception=>e @laststatuscode = e.to_s Log4Ienso.log.P_INFO("exception in register " + e.to_s ) Log4Ienso.log.P_INFO("[LTE] " + e.to_s) `rm -rf #{@sessionfile}` # maybe the token is expired return end @laststatuscode = response.code.to_s if response.code == 200 @token = JSON.parse(response.body)['token'] `echo #{@token} > #{@sessionfile}` Log4Ienso.log.P_INFO('got token from server') else Log4Ienso.log.P_INFO("Failed to register with end point " + response.body) return (1) end end return 0 end def getCommands(starttype) if starttype == COLD_BOOT response = RestClient.get(@api_end_point+"/device/commands?new=1",{"Authorization" => @token, 'accept' => 'application/json' }) Log4Ienso.log.P_NOTICE("FETCHING SERVER CMDS DUE TO COLD BOOT") else response = RestClient.get(@api_end_point+"/device/commands",{"Authorization" => @token, 'accept' => 'application/json' }) end Log4Ienso.log.P_INFO("[LTE] server commands" + response.code.to_s) Log4Ienso.log.P_INFO("[LTE] server commands" + response.body) return response.body end def ackServerAfterRequest(id) response = RestClient.put(@api_end_point+"/device/commands?id=#{id}", {}, { 'Content-Type' => 'application/x-www-form-urlencoded', 'Authorization' => @token, 'Accept' => 'application/json' }) end def getDCIMName(file) basename = File.basename(file,File.extname(file)) fixedbasename = basename[0..-2] actualname = fixedbasename + File.extname(file) return actualname end def getThumbnailCDN(filename) #datetime = Time.now filename = File.basename(filename) #datetaken = URI.escape(datetime.strftime('%Y-%m-%dT%H:%M:%S')) mediatype = 0 i = filename.index("V") thumbBytes=0 fullBytes=0 thumbfile = @thumb_path + filename if !File.file?(thumbfile) Log4Ienso.log.P_INFO("exception file does not exist " + thumbfile ) raise end begin # to handle old file types not uploaded dcimfilename = getDCIMName(filename) fullfile = @pic_path +dcimfilename thumbBytes = File.size(thumbfile) if thumbBytes < 1024 Log4Ienso.log.P_INFO("exception incomplete pic capture - reset the cam module #{thumbfile}" ) `rm -f #{thumbfile}` $cammoduleresecount +=1 return end fullBytes = File.size(fullfile) Log4Ienso.log.P_INFO("Geting cdn for thumb size #{thumbBytes} and full DCIM file of size #{fullBytes}") rescue Log4Ienso.log.P_INFO("Old format files found where equivalent DCIM file not found or Zero size thunbs ") thumbBytes = 0 # send zero for not until all old files clear up fullBytes = 0 end if i == nil mediatype = 0 else mediatype = 1 end begin datetaken = EXIFR::JPEG.new(thumbfile).date_time_original rescue Exception => e Log4Ienso.log.P_INFO(e.backtrace) datetaken = URI.escape(datetime.strftime('%Y-%m-%dT%H:%M:%S')) ensure begin response = RestClient.put(@api_end_point+"/image/thumbnail?name=#{URI.escape(thumbfile)}&datetaken=#{datetaken}&mediatype=#{mediatype}&thumbBytes=#{thumbBytes}&fullBytes=#{fullBytes}", {}, { 'Content-Type' => 'application/x-www-form-urlencoded', 'Authorization' => @token, 'Accept' => 'application/json' }) rescue Exception=>e @laststatuscode = e.to_s Log4Ienso.log.P_INFO("exception in getting cdn " + e.to_s ) Log4Ienso.log.P_INFO("[LTE] " + response.code.to_s) Log4Ienso.log.P_INFO("[LTE] " + e.to_s) `rm -rf #{sessionfile}` # maybe the token is expired raise end Log4Ienso.log.P_INFO("[LTE] thumbnail cdn " + response.code.to_s) Log4Ienso.log.P_INFO("[LTE] thumbnail cdn " + response.body) #@laststatuscode = response.code.to_s if response.code == 200 $usbErrorCount = 0 #if control is here the usb modem is surely connected and can be reset json_resp = JSON.parse(response.body) Log4Ienso.log.P_INFO(json_resp) cdn_url = json_resp['url'] cdn_host =URI(json_resp['url']).host id = json_resp['id'] else Log4Ienso.log.P_INFO("Failed to get CDN" + response.body + " " + response.code.to_s) `rm -rf #{sessionfile}` # maybe the token is expired @laststatuscode = "1" return end return cdn_url,cdn_host,id end end def getImageOrVideoCDN(filename,id) response = RestClient.put(@api_end_point+"/image/full?name=#{URI.escape(filename)}&id=#{id}", {}, { 'Content-Type' => 'application/x-www-form-urlencoded', 'Authorization' => @token, 'Accept' => 'application/json' }) Log4Ienso.log.P_INFO("[LTE] hires or video cdn " + response.code.to_s) Log4Ienso.log.P_INFO("[LTE] hires or video cdn " + response.body) #@laststatuscode = response.code.to_s if response.code == 200 json_resp = JSON.parse(response.body) Log4Ienso.log.P_INFO(json_resp) cdn_url = json_resp['url'] cdn_host =URI(json_resp['url']).host id = json_resp['id'] else Log4Ienso.log.P_INFO("Failed to get CDN") `rm -rf #{sessionfile}` # maybe the token is expired @laststatuscode = "1" return end return cdn_url,cdn_host,id end def reportFileNotFound(id) response = RestClient.put(@api_end_point+"/image/error?id=#{id}", {}, { 'Content-Type' => 'application/x-www-form-urlencoded', 'Authorization' => @token, 'Accept' => 'application/json' }) #@laststatuscode = response.code.to_s if response.code == 200 json_resp = JSON.parse(response.body) Log4Ienso.log.P_INFO(json_resp) cdn_url = json_resp['url'] cdn_host =URI(json_resp['url']).host id = json_resp['id'] else Log4Ienso.log.P_INFO("Failed to get CDN") `rm -rf #{sessionfile}` # maybe the token is expired @laststatuscode = "1" return end return 0 end def uploadThumbnail(filename,cdn_url,cdn_host, id) content_length = File.size(filename) response = RestClient.put(cdn_url, File.new(filename).read, { 'Host' => cdn_host, 'Content-type' => 'image/jpeg', 'Content-Length' => content_length, } ) Log4Ienso.log.P_INFO("[LTE] upload thumb " + response.code.to_s) Log4Ienso.log.P_INFO("[LTE] upload thumb " + response.body) Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} [LTE] upload thumb ,response.code=#{response.code.to_s}, response.body=#{response.body}" ) #@laststatuscode = response.code.to_s if response.code == 200 response = RestClient.put(@api_end_point+"/image/thumbnailcomplete?id=#{id}", {}, { 'Content-Type' => 'application/json', 'Authorization' => @token, 'Accept' => 'application/json' }) Log4Ienso.log.P_INFO("[LTE] upload thumb complete " + response.code.to_s) Log4Ienso.log.P_INFO("[LTE] upload thumb complete " + response.body) Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} [LTE] upload thumb ,response.code=#{response.code.to_s}, response.body=#{response.body}" ) #@laststatuscode = response.code.to_s if response.code == 200 Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} Image thumbnail successfully uploaded") return 0 else Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} Failed to upload") end else Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} Failed to get correct response when uploadng") return 1 end return 1 end def getStatusCode return @laststatuscode end def uploadHiResImageOrVideo(filename,cdn_url,cdn_host,id) content_length = File.size(filename) ext = File.extname(filename) if ext == ".jpg" || ext == ".jpeg" media="IMAGE" elsif ext == ".mpeg" || ext == ".mov" || ext == ".mp4" media="MOVIE" end if media == "IMAGE" mtype ='image/jpeg' elsif media == "MOVIE" mtype = 'video/mp4' # start= Time.now # Log4Ienso.log.P_NOTICE("Starting encoding at time " + start.to_s) fn = cut_video_length(filename) filename = fn if fn != nil # fn2 = change_video_scale(filename) # filename = fn2 if fn2 != nil # endtime = Time.now #diff = endtime - start # Log4Ienso.log.P_NOTICE("Ending encoding at time " + endtime.to_s + " total time is " + diff.to_s) else mtype ='image/jpeg' end response = RestClient.put(cdn_url, File.new(filename).read, { 'Host' => cdn_host, 'Content-type' => mtype, 'Content-Length' => content_length, } ) Log4Ienso.log.P_INFO("[LTE] upload hires or video " + response.code.to_s) Log4Ienso.log.P_INFO("[LTE] upload hires or video " + response.body) if response.code == 200 response = RestClient.put(@api_end_point+"/image/fullcomplete?id=#{id}", {}, { 'Content-Type' => 'application/json', 'Authorization' => @token, 'Accept' => 'application/json' }) Log4Ienso.log.P_INFO("[LTE] upload hires complete " + response.code.to_s) Log4Ienso.log.P_INFO("[LTE] upload hires complete" + response.body) if response.code == 200 Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} Hi Res image #{filename} successfully uploaded") return 0 else Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} Failed to upload") end else Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} Failed to get correct response when uploadng") return 1 end return 1 end # Note # The uploadlogfile is not uploaded the usual way to S3. It is to a public bucket # At time of development, the zipit spec v1.2.5 is wrong and the headers are not required and # url requires log file name def uploadLogFile(cdn_url) Log4Ienso.log.P_INFO("Starting cleanup" ) `rm /var/log/*.zip` #remove old zip files `rm /var/log/impulse` #remove old file used for upload system("cat `ls -tr /var/log/message*` >> /var/log/impulse") #combine all the log files, oldest first ,latest last into one Log4Ienso.log.P_INFO("Finished cleanup" ) combinedtemplogfile = '/var/log/impulse' logstart = `cat /var/log/impulse | head -1 | tr -s " " | cut -d" " -f1-3` logend = `cat /var/log/impulse | tail -1 | tr -s " " | cut -d" " -f1-3` logstart = logstart.strip.chomp logend = logend.strip.chomp starttime = `date -D'#{logstart}' +%Y%m%d%H%M%S` endtime = `date -D'#{logend}' +%Y%m%d%H%M%S` starttime = starttime.strip.chomp endtime = endtime.strip.chomp Log4Ienso.log.P_NOTICE("starttime is #{starttime} and endtime is #{endtime} ") filename = starttime+"-"+endtime+".log.zip" Log4Ienso.log.P_NOTICE("filename is #{filename} ") filenamewithpath = '/var/log/'+starttime+"-"+endtime+".log.zip" Log4Ienso.log.P_NOTICE("file path+name #{filenamewithpath} ") `zip #{filenamewithpath} #{combinedtemplogfile}` Log4Ienso.log.P_INFO("[LTE] upload log file name" + filename) content_length = File.size(filenamewithpath) Log4Ienso.log.P_INFO("Size of zip is :" + content_length.to_s ) mtype ="application/zip" cdn_host ="s3.amazonaws.com" cdn_url = cdn_url + filename Log4Ienso.log.P_INFO("upload cdn in :" + cdn_url ) begin response = RestClient.put(cdn_url, File.new(filenamewithpath).read, { } ) rescue Exception=>e Log4Ienso.log.P_INFO("exception in upload log " + e.to_s ) Log4Ienso.log.P_INFO("[LTE] " + e.to_s) raise end Log4Ienso.log.P_INFO("[LTE] upload log file " + response.body) if response.code == 200 Log4Ienso.log.P_INFO("Upload log successful") else Log4Ienso.log.P_INFO("Failed to get correct response when uploadng") return 1 end return 1 end #status command def setConfigStatus(storageused,storagesize,battery,latitude,longitude,rssi,trackingstate) getEnvValues rssi = modifyRSSIForZipIt(rssi) if @env_pir=="med" pir_senstivity="medium" else pir_senstivity = @env_pir end trackingmode = true if trackingstate == 1 trackingmode = false if trackingstate == 0 Log4Ienso.log.P_NOTICE("tracking mode is set to #{trackingmode} where tracking state is #{trackingstate}") avgTTFF = 0 if $gpsTTFFcnt > 0 avgTTFF = $gpsTTFFsum / $gpsTTFFcnt avgTTFF = avgTTFF.round(1) end gpsStats = "#{$gpsTTFFcnt}/#{$gpsFixAttemps} @ #{avgTTFF}s" Log4Ienso.log.P_INFO("Debug information has been added to config status") configstatus = { "status": { "name": @env_cameraname , "phone": "", "email": "#{$trigger}", "wirelessenabled": @env_wireless, #check value true/flase "reportinterval": @env_reportinterval, "storageused": storageused, "storagesize": storagesize, "overwrite": @env_overwrite, "battery": battery, "capturemode": @env_capturemode, "capturecount": @env_capturecount , "shutterspeed": @env_shutterspeed, "imageformat": @env_picformat.to_i, "imageresolution": @env_imageresolution, "movieresolution": @env_movieresolution , "movielength": @env_movielength, "pirdelay": @env_pirdelay , "pirsensitivity": pir_senstivity, "pirmode": @env_pirmode, "pirtimes": { "MF": { "block1": { "camera": @mf_camera[0], "time": @mf_period[0] }, "block2": { "camera": @mf_camera[1], "time": @mf_period[1] }, "block3": { "camera": @mf_camera[2], "time": @mf_period[2] }, "block4": { "camera": @mf_camera[3], "time": @mf_period[3] } }, "SAT": { "block1": { "camera": @sat_camera[0], "time": @sat_period[0] }, "block2": { "camera": @sat_camera[1], "time": @sat_period[1] }, "block3": { "camera": @sat_camera[2], "time": @sat_period[2] }, "block4": { "camera": @sat_camera[3], "time": @sat_period[3] } }, "SUN": { "block1": { "camera": @sun_camera[0], "time": @sun_period[0] }, "block2": { "camera": @sun_camera[1], "time": @sun_period[1] }, "block3": { "camera": @sun_camera[2], "time": @sun_period[2] }, "block4": { "camera": @sun_camera[3], "time": @sun_period[3] } } }, "debug": { "atERRORs": $atERRORs, "tzERRORs": $tzERRORs, "ftpERRORs": $ftpERRORs, "gpsFIXes": "#{gpsStats}" }, "ledintensity": @env_ledintensity, "showtimestamp": @env_showtimestamp , "fieldscan": @env_fieldscan, "scaninterval": @env_interval_a, #no place for interval b "scan2interval": @env_interval_b, "scan1start": @env_scan1start, "scan1end": @env_scan1end , "scan2start": @env_scan2start, "scan2end": @env_scan2end , "embedgps": @env_embedgps, "latitude": latitude, "longitude": longitude, "trackingMode": trackingmode, "rssi": rssi, "lastupdate": $lastupdatetime } } headers = { 'Content-Type' => 'application/json', 'Authorization' => @token, 'Accept' => 'application/json' } begin response = RestClient.post(@api_end_point+"/device/status", configstatus.to_json, headers) rescue Exception=>e @laststatuscode = e.to_s Log4Ienso.log.P_INFO("exception in setting status " + e.to_s ) Log4Ienso.log.P_INFO("[LTE] " + response.to_s) Log4Ienso.log.P_INFO("[LTE] " + e.to_s) raise end @laststatuscode = response.code.to_s if response.code == 200 Log4Ienso.log.P_INFO('ConfigStatus set on server') else Log4Ienso.log.P_INFO("Failed to set status " + response.body) return (1) end return 0 end def scaleBatteryValue(battery) return battery #do not scale, just send the raw value =begin # the following commented out code is based on the Zipit 1.29 document # where the camera was providing battery values according to the zipit battery scale # this is not the case any more and zipit can use the raw values. x= ((battery/10).ceil)*10.0 x = 10 if x==20 x = 25 if x == 30 x = 40 if x == 50 x = 60 if x == 70 x = 80 if x >=80 && x < 90 x = 100 if x>=90 x = x.to_i.to_s return (x) =end end # status v2 command def setStatus(storageused,storagesize,battery,latitude,longitude,rssi,gpstime ,trackingstate , wifistate) ssidname="" trackingstate = 0 if trackingstate == nil wifitimeout = nil errorid = 0 errstring="WLAN not active " + $trigger battery = scaleBatteryValue(battery) Log4Ienso.log.P_INFO("Status value is #{storageused} #{storagesize} #{battery} #{latitude} #{longitude} ") Log4Ienso.log.P_INFO("rssi=#{rssi} gpstime=#{gpstime} track=#{trackingstate} wifi=#{wifistate}") rssi = modifyRSSIForZipIt(rssi) if wifistate == 1 wlan=`ifconfig -a | tr -s " "| grep w | cut -d" " -f5 | head -1` prefix="Bushnell" ssidname=prefix+wlan x= Time.now x= x+$wifi_timeout #in seconds wifitimeout = x.strftime("%Y-%m-%dT%H:%M:%S") wifitimeout = wifitimeout + $camera_timezone errstring = "WLAN started " +$trigger Log4Ienso.log.P_INFO(errstring) if ssidname.length < 1 errorid = 1 errstring = "Failed to start WLAN, try again " +$trigger else ssidname = ssidname.strip.chomp end end status = { "status": { "storageused": storageused, "storagesize": storagesize, "battery": battery, "latitude": latitude, "longitude": longitude, "rssi": rssi, "time": gpstime, "trackingactive": trackingstate, "wifi": { "active": wifistate, "ssid": ssidname, "error": errorid, "errorMessage": errstring, "FWver": $firmware_ver, "timeout": wifitimeout } } } Log4Ienso.log.P_INFO("ssid value is #{ssidname}") headers = { 'Content-Type' => 'application/json', 'Authorization' => @token, 'Accept' => 'application/json' } begin response = RestClient.post(@api_end_point+"/device/statusv2", status.to_json, headers) rescue Exception=>e @laststatuscode = e.to_s Log4Ienso.log.P_INFO("exception in setting status " + e.to_s ) Log4Ienso.log.P_INFO("[LTE] " + response.code.to_s) Log4Ienso.log.P_INFO("[LTE] " + e.to_s) raise end @laststatuscode = response.code.to_s if response.code == 200 Log4Ienso.log.P_INFO('Status set on server') else Log4Ienso.log.P_INFO("Failed to set status " + response.body) return (1) end return 0 end def getFirmWareManifest hardwaretype = '1' begin response = RestClient.get(@api_end_point+"/device/firmware?hardwareType=#{hardwaretype}", {"Authorization" => @token, 'accept' => 'application/json' }) rescue Exception=>e Log4Ienso.log.P_ERR("exception in setting status " + e.to_s ) end if response != nil return response.body end end def modifyRSSIForZipIt(rssi) nrssi=0 nrssi = 11 if rssi == 0 nrssi = 11 if rssi == 1 nrssi = 18 if rssi == 2 nrssi = 25 if rssi == 3 nrssi = 32 if rssi == 4 nrssi = 39 if rssi == 5 return nrssi end =begin {"id"=>216, "config"=>{"Name"=>"RogersU1", "WirelessEnabled"=>true, "ReportInterval"=>"quick", "Overwrite"=>false, "CaptureMode"=>"i", "CaptureCount"=>1, "ShutterSpeed"=>"medium", "ImageResolution"=>5, "MovieResolution"=>720, "MovieLength"=>10, "PIRDelay"=>17, "PIRSensitivity"=>"medium", "LEDIntensity"=>"high", "ShowTimestamp"=>true, "FieldScan"=>false, "ScanInterval"=>0, "Scan1Start"=>"00:00:00", "Scan1End"=>"00:00:00", "Scan2Start"=>"00:00:00", "Scan2End"=>"00:00:00", "EmbedGPS"=>true, "Latitude"=>38.96189, "Longitude"=>-94.72194}, "uploadfiles"=>[], "deleteall"=>false, "firmware"=>nil, "captureimage"=>false, "uploadlogs"=>nil} {"id":561,"config":{"Name":"RogCan","WirelessEnabled":true,"ReportInterval":"quick","Overwrite":true,"CaptureMode":"i","CaptureCount":1, "ShutterSpeed":"low","ImageResolution":5,"MovieResolution":640,"MovieLength":10,"PIRDelay":10,"PIRSensitivity":"medium","LEDIntensity":"medium", "ShowTimestamp":true,"FieldScan":false,"ScanInterval":0,"Scan1Start":"00:00:00","Scan1End":"00:00:00","Scan2Start":"00:00:00","Scan2End":"00:00:00", "EmbedGPS":true,"Latitude":0,"Longitude":0},"uploadfiles":[],"deleteall":false,"firmware":null,"captureimage":false,"uploadlogs":null} : =end def parseServerCommand(cmd) configchanged = 0 uploadfrequency = nil uploadloglevel = nil uploadlogurl = nil ret = Hash[ "imgresolution" => "false", "movieresolution" => "false", "pirmode" => "false", "fieldscan" => "false", "pirdelay" => "false", "ledintensity" => "false", "movielength" => "false", "shutterspeed" => "false", "showtimestamp" => "false", "tracking" => "false", "timeofoperation" => "false", "pirsensitivity" => "false" , "capture_mode" => "false"] Log4Ienso.log.P_INFO("Parsing server commands..." ) begin json_resp = JSON.parse(cmd) Log4Ienso.log.P_INFO(json_resp) id = json_resp["id"] # ack it first before processing Log4Ienso.log.P_INFO(" id is "+id.to_s) ackServerAfterRequest(id) Log4Ienso.log.P_INFO("||| Completed ACK with server |||") #now process the commands name = json_resp["Name"] uploadfiles = json_resp["uploadfiles"] deleteall = json_resp["deleteall"] firmware = json_resp["firmware"] Log4Ienso.log.P_INFO("||| #{firmware.to_s} |||") if firmware != nil captureimage = json_resp["captureimage"] Log4Ienso.log.P_INFO("Completed ACK with server 1" ) uploadlogs = json_resp["uploadlogs"] activatewifi = json_resp["activatewifi"] trackingactive = json_resp["trackingactive"] if uploadlogs != nil uploadfrequency = json_resp["uploadlogs"]["frequency"] uploadloglevel = json_resp["uploadlogs"]["loglevel"] uploadlogurl = json_resp["uploadlogs"]["url"] end config = json_resp["config"] if id.to_i > 0 && firmware == nil getEnvValues configchanged = 1 Log4Ienso.log.P_INFO("STARTING ENV UPDATE ..." ) cameraname = config['Name'] Log4Ienso.log.P_INFO("1 ..." + cameraname ) cameraname = cameraname.strip.chomp Log4Ienso.log.P_INFO("remote cam name is " + cameraname ) #update camera if cameraname != @env_cameraname Log4Ienso.log.P_INFO("camera names do not match" ) setValue('camera_name',cameraname) Log4Ienso.log.P_INFO("camera name updated" ) else Log4Ienso.log.P_INFO("camera names match" ) end #wireless Log4Ienso.log.P_INFO("checking wireless" ) wireless = config['WirelessEnabled'] wireless = 'on' if wireless == true wireless = 'off' if wireless == false if wireless != @env_wireless Log4Ienso.log.P_INFO("wrieless settings changed") setValue('wirless_on/off',wireless) else Log4Ienso.log.P_INFO("wrieless settings NOT changed") end Log4Ienso.log.P_INFO("end of wireless" ) #reportinterval Log4Ienso.log.P_INFO("checking report interval" ) reportinterval = config['ReportInterval'] # comm frequency quick, daily, weekly,never reportinterval = "now" if reportinterval == "quick" reportinterval = reportinterval.strip.chomp if reportinterval != @env_reportinterval Log4Ienso.log.P_INFO("report interval changed" ) setValue('report_interval',reportinterval) else Log4Ienso.log.P_INFO("report interval not changed" ) end #overwrite Log4Ienso.log.P_INFO("checking overwrite" ) overwrite = config['Overwrite'] overwrite = "on" if overwrite == true overwrite ="off" if overwrite ==false if overwrite != @env_overwrite && ( overwrite == "on" || overwrite == "off" ) Log4Ienso.log.P_INFO("overwrite changed" ) setValue('overwrite',overwrite) else Log4Ienso.log.P_INFO("overwrite not changed" ) end #capture mode Log4Ienso.log.P_INFO("checking capture mode" ) mode = config['CaptureMode'] omode = mode mode = mode.strip.chomp mode = "image" if mode == 'i' mode = "video" if mode == 'm' mode = "hybrid" if mode == 'h' if mode == 'hybrid' setValue('hybrid', 'on') else setValue('hybrid', 'off') end if omode != @env_capturemode && ( mode == "image" || mode =="video" || mode == "hybrid") mode = "video" if mode == "hybrid" # now storing hybrid in different node, on server it is together Log4Ienso.log.P_INFO("capture mode changed" ) setValue('capture_mode', mode) ret["capture_mode"] = mode else Log4Ienso.log.P_INFO("capture mode not changed" ) end #capture count Log4Ienso.log.P_INFO("checking capture count" ) capturecount = config['CaptureCount'] #no interface if capturecount >=1 and capturecount <=5 capturecount='1_copy' if capturecount == 1 capturecount='2_copy' if capturecount == 2 capturecount='3_copy' if capturecount == 3 capturecount='4_copy' if capturecount == 4 capturecount='5_copy' if capturecount == 5 if capturecount != @env_capturecount Log4Ienso.log.P_INFO("capture count changed" ) setValue('capture_count',capturecount) else Log4Ienso.log.P_INFO("capture count not changed" ) end end #shutter speed Log4Ienso.log.P_INFO("checking shutter speed" ) shutterspeed = config['ShutterSpeed'] #only night vision shutter speed shutterspeed = "med" if shutterspeed == "medium" if shutterspeed == 'low' || shutterspeed =='med' || shutterspeed =='high' if shutterspeed != @env_shutterspeed Log4Ienso.log.P_INFO("shutter speed has changed" ) setValue('shutter_speed', shutterspeed) ret["shutterspeed"] = shutterspeed else Log4Ienso.log.P_INFO("shutter speed has not changed" ) end end #image resolution and pic format Log4Ienso.log.P_INFO("checking image resolution and pic format" ) imgresolution = config['ImageResolution'] picformat = config['ImageFormat'] Log4Ienso.log.P_INFO("image resolution from server #{imgresolution} and on cam is #{@env_imageresolution}" ) Log4Ienso.log.P_INFO("pic format from server #{picformat} and on cam is #{@env_picformat}" ) imgresolution = imgresolution.to_s imgresolution ='2' if imgresolution == '3' if imgresolution == '2' || imgresolution == '5' || imgresolution == '8' || imgresolution == '99' imgresolution = '20' if imgresolution == '99' if imgresolution != @env_imageresolution Log4Ienso.log.P_INFO("image resolution has changed" ) setValue('image_resoluition',imgresolution) @res_change = 1 else Log4Ienso.log.P_INFO("image resolution has not changed" ) end end if picformat != @env_picformat newval = "3to2" if picformat.to_s == "0" newval = "16to9" if picformat.to_s == "1" setValue('pic_format', newval ) @res_change = 1 Log4Ienso.log.P_NOTICE ("picformat has changed #{ret["picformat"]}") else Log4Ienso.log.P_NOTICE ("picformat has NOT changed") end ret["imgresolution"] = imgresolution if @res_change == 1 @res_change = 0 #movie resolution Log4Ienso.log.P_INFO("checking movie resolution" ) movieresolution = config['MovieResolution'] #no interface movieresolution = movieresolution.to_s.strip Log4Ienso.log.P_INFO("resolution is " + movieresolution.to_s ) movieresolution = "640x480" if movieresolution == "640" movieresolution = "720p30" if movieresolution == "720" movieresolution = "1080p30" if movieresolution == "1080" if movieresolution == "640x480" || movieresolution == "720p30" || movieresolution == "1080p30" Log4Ienso.log.P_INFO("checking movie resolution .....#{movieresolution} with #{@env_movieresolution}" ) if movieresolution != @env_movieresolution Log4Ienso.log.P_INFO("checking movie changed" ) setValue('movie_resoluition',movieresolution) ret["movieresolution"] = movieresolution else Log4Ienso.log.P_INFO("checking movie not changed" ) end end #movie length Log4Ienso.log.P_INFO("checking movie length") movielength = config['MovieLength'] if movielength > 1 && movielength < 61 movielength = movielength.to_s+"_second" if movielength != @env_movielength Log4Ienso.log.P_INFO("movie length has changed") setValue('movie_length',movielength) ret["movielength"] = movielength else Log4Ienso.log.P_INFO("movie length not changed") end end #pir delay Log4Ienso.log.P_INFO("pir delay") pirdelay = config['PIRDelay'] #pir delay if $model=='primos' pirdelay = 10 if pirdelay < 10 #primos camera supports 10+ second pir intervals Log4Ienso.log.P_NOTICE("PRIMOS time < 10 IGNORED") end if pirdelay >= 1 && pirdelay <= 3600 if pirdelay >= 60 pirdelay = pirdelay / 60 pirdelay = pirdelay.to_s+"_minute" else pirdelay = pirdelay.to_s+"_second" end if pirdelay != @env_pirdelay Log4Ienso.log.P_INFO("pirdelay has changed") setValue('imaage_interval',pirdelay) ret["pirdelay"] = pirdelay else Log4Ienso.log.P_INFO("pirdelays not changed") end end #pir senstivity Log4Ienso.log.P_INFO("pir sensitivity") pirsensitivity = config['PIRSensitivity'] #pir senstivity pirsensitivity = "med" if pirsensitivity == "medium" if pirsensitivity=="auto" || pirsensitivity=="low" || pirsensitivity=="med" || pirsensitivity=="high" if pirsensitivity != @env_pirsensitivity Log4Ienso.log.P_INFO("pirsensitivity has changed") setValue('pir',pirsensitivity) ret["pirsensitivity"] = pirsensitivity else Log4Ienso.log.P_INFO("pirsensitivity not changed") end end #pir mode Log4Ienso.log.P_INFO("pir mode") pirmode = config['PIRMode'] #pir senstivity if pirmode == "on" || pirmode == "off" || pirmode == "day" || pirmode == "night" || pirmode == "timer" if $model == 'primos' pirmode ="on" if pirmode == "timer" #primos does not support pir timer Log4Ienso.log.P_NOTICE("PRIMOS timer ignored") end if pirmode != @env_pirmode Log4Ienso.log.P_INFO("pir mode has changed") setValue('pir_mode',pirmode) ret["pirmode"] = pirmode else Log4Ienso.log.P_INFO("pirmode not changed") end end # embed gps Log4Ienso.log.P_INFO("EmbedGPS") embedgps = config['EmbedGPS'] embedgps = "on" if embedgps == true embedgps = "off" if embedgps == false if embedgps == "on" || embedgps == "off" Log4Ienso.log.P_INFO("embedgps is changed") setValue('embedded_gps', embedgps) else Log4Ienso.log.P_INFO("embedgps not changed") end #led intensity Log4Ienso.log.P_INFO("led intensity") ledintensity = config['LEDIntensity'] if ledintensity == "low" || ledintensity =="medium" || ledintensity =="high" ledintensity = "med" if ledintensity == "medium" if ledintensity != @env_ledintensity Log4Ienso.log.P_INFO("led intensity has changed") setValue('led_power',ledintensity) ret["ledintensity"] = ledintensity else Log4Ienso.log.P_INFO("led intensity has not changed") end end # timestamp Log4Ienso.log.P_INFO("timestamp") showtimestamp = config['ShowTimestamp'] showtimestamp = "on" if showtimestamp == true showtimestamp = "off" if showtimestamp == false if showtimestamp == "on" || showtimestamp == "off" Log4Ienso.log.P_INFO("show timestamp is changed") setValue('show_timestamp', showtimestamp) ret["showtimestamp"] = showtimestamp else Log4Ienso.log.P_INFO("show timestamp not changed") end #tracking Log4Ienso.log.P_INFO("tracking") tracking = config['TrackingMode'] tracking = 'on' if tracking == true tracking = 'off' if tracking == false Log4Ienso.log.P_NOTICE ("The vlaue of tracking is [#{tracking}]") if tracking != @env_tracking setValue('tracking', tracking ) ret["tracking"] = tracking Log4Ienso.log.P_NOTICE ("tracking has changed #{ret["tracking"]}") else Log4Ienso.log.P_NOTICE ("tracking has NOT changed") end # time of operation Log4Ienso.log.P_NOTICE ("Time of operation") if pirmode == "timer" Log4Ienso.log.P_NOTICE ("PIR mode is timer") n = json_resp["config"]["PIRTimes"]["MF"] if n != nil mfcam1 = json_resp["config"]["PIRTimes"]["MF"]["Block1"]["Camera"] mfcamtime1 = json_resp["config"]["PIRTimes"]["MF"]["Block1"]["Time"] mfcam2 = json_resp["config"]["PIRTimes"]["MF"]["Block2"]["Camera"] mfcamtime2 = json_resp["config"]["PIRTimes"]["MF"]["Block2"]["Time"] mfcam3 = json_resp["config"]["PIRTimes"]["MF"]["Block3"]["Camera"] mfcamtime3 = json_resp["config"]["PIRTimes"]["MF"]["Block3"]["Time"] mfcam4 = json_resp["config"]["PIRTimes"]["MF"]["Block4"]["Camera"] mfcamtime4 = json_resp["config"]["PIRTimes"]["MF"]["Block4"]["Time"] str=@env.get_env('time_ofoperation.off_on') puts(str) str[0][0] = mfcam1.to_s str[0][2] = mfcam2.to_s str[0][4] = mfcam3.to_s str[0][6] = mfcam4.to_s Log4Ienso.log.P_NOTICE ("M-F on/off as rcvd #{str}") @env.save_env_val('time_ofoperation.off_on',str) #update the time of operation time slots str=@env.get_env('time_ofoperation.time') begin str[0][0..4] = checkHourMin(mfcamtime1.strip.chomp) str[0][6..10] = checkHourMin(mfcamtime2.strip.chomp) str[0][12..16] = checkHourMin(mfcamtime3.strip.chomp) str[0][18..22] = checkHourMin(mfcamtime4.strip.chomp) if ( getAbsTime(str[0][0..4]) < getAbsTime(str[0][6..10]) && getAbsTime(str[0][6..10]) < getAbsTime(str[0][12..16]) && getAbsTime(str[0][12..16]) < getAbsTime(str[0][18..22]) ) @env.save_env_val('time_ofoperation.time',str) ret["timeofoperation"] = str else Log4Ienso.log.P_NOTICE ("Error in time of operation time syntax") end rescue Log4Ienso.log.P_NOTICE ("Error in time of operation time syntax") end end n = json_resp["config"]["PIRTimes"]["SAT"] if n != nil satcam1 = json_resp["config"]["PIRTimes"]["SAT"]["Block1"]["Camera"] satcamtime1 = json_resp["config"]["PIRTimes"]["SAT"]["Block1"]["Time"] satcam2 = json_resp["config"]["PIRTimes"]["SAT"]["Block2"]["Camera"] satcamtime2 = json_resp["config"]["PIRTimes"]["SAT"]["Block2"]["Time"] satcam3 = json_resp["config"]["PIRTimes"]["SAT"]["Block3"]["Camera"] satcamtime3 = json_resp["config"]["PIRTimes"]["SAT"]["Block3"]["Time"] satcam4 = json_resp["config"]["PIRTimes"]["SAT"]["Block4"]["Camera"] satcamtime4 = json_resp["config"]["PIRTimes"]["SAT"]["Block4"]["Time"] str=@env.get_env('time_ofoperation.off_on') puts(str) str[1][0] = satcam1.to_s str[1][2] = satcam2.to_s str[1][4] = satcam3.to_s str[1][6] = satcam4.to_s @env.save_env_val('time_ofoperation.off_on',str) #update the time of operation time slots str=@env.get_env('time_ofoperation.time') begin str[1][0..4] = checkHourMin(satcamtime1.strip.chomp) str[1][6..10] = checkHourMin(satcamtime2.strip.chomp) str[1][12..16] = checkHourMin(satcamtime3.strip.chomp) str[1][18..22] = checkHourMin(satcamtime4.strip.chomp) if ( getAbsTime(str[1][0..4]) < getAbsTime(str[1][6..10]) && getAbsTime(str[1][6..10]) < getAbsTime(str[1][12..16]) && getAbsTime(str[1][12..16]) < getAbsTime(str[1][18..22]) ) @env.save_env_val('time_ofoperation.time',str) ret["timeofoperation"] = str else Log4Ienso.log.P_NOTICE ("Error in time of operation time syntax") end rescue Log4Ienso.log.P_NOTICE ("Error in time of operation time syntax") end end n = json_resp["config"]["PIRTimes"]["SUN"] if n != nil suncam1 = json_resp["config"]["PIRTimes"]["SUN"]["Block1"]["Camera"] suncamtime1 = json_resp["config"]["PIRTimes"]["SUN"]["Block1"]["Time"] suncam2 = json_resp["config"]["PIRTimes"]["SUN"]["Block2"]["Camera"] suncamtime2 = json_resp["config"]["PIRTimes"]["SUN"]["Block2"]["Time"] suncam3 = json_resp["config"]["PIRTimes"]["SUN"]["Block3"]["Camera"] suncamtime3 = json_resp["config"]["PIRTimes"]["SUN"]["Block3"]["Time"] suncam4 = json_resp["config"]["PIRTimes"]["SUN"]["Block4"]["Camera"] suncamtime4 = json_resp["config"]["PIRTimes"]["SUN"]["Block4"]["Time"] str=@env.get_env('time_ofoperation.off_on') puts(str) str[2][0] = suncam1.to_s str[2][2] = suncam2.to_s str[2][4] = suncam3.to_s str[2][6] = suncam4.to_s @env.save_env_val('time_ofoperation.off_on',str) #update the time of operation time slots str=@env.get_env('time_ofoperation.time') begin str[2][0..4] = checkHourMin(suncamtime1.strip.chomp) str[2][6..10] = checkHourMin(suncamtime2.strip.chomp) str[2][12..16] = checkHourMin(suncamtime3.strip.chomp) str[2][18..22] = checkHourMin(suncamtime4.strip.chomp) if ( getAbsTime(str[2][0..4]) < getAbsTime(str[2][6..10]) && getAbsTime(str[2][6..10]) < getAbsTime(str[2][12..16]) && getAbsTime(str[2][12..16]) < getAbsTime(str[2][18..22]) ) @env.save_env_val('time_ofoperation.time',str) ret["timeofoperation"] = str else Log4Ienso.log.P_NOTICE ("Error in time of operation time syntax") end rescue Log4Ienso.log.P_NOTICE ("Error in time of operation time syntax") end end else Log4Ienso.log.P_INFO("Skipping time of operation, mode is #{pirmode} ") end # field scanScan1Start Log4Ienso.log.P_INFO("Field scan ") fieldscan = config['FieldScan'] fieldscan = "on" if fieldscan == true fieldscan = "off" if fieldscan == false if fieldscan == "on" || fieldscan =="off" if fieldscan != @env_fieldscan || fieldscan == "on" Log4Ienso.log.P_NOTICE("field scan changed") setValue('field_scan', fieldscan) ret["fieldscan"] = fieldscan fieldscaninterval1 = config['ScanInterval'] #only interval a fieldscaninterval2 = config['Scan2Interval'] #only interval a if fieldscaninterval1.to_i >= 1 && fieldscaninterval1.to_i <= 60 fieldscaninterval1 = fieldscaninterval1.to_s + "_minute2" setValue('interval_a', fieldscaninterval1) end if fieldscaninterval2.to_i >= 1 && fieldscaninterval2.to_i <= 60 fieldscaninterval2 = fieldscaninterval2.to_s + "_minute2" setValue('interval_b', fieldscaninterval2) end scan1start = config['Scan1Start'] scan1start = checkHourMin(scan1start) Log4Ienso.log.P_INFO("scan1start #{scan1start}") if scan1start.to_i >=0 setValue('start_time_a', scan1start) end scan1end = config['Scan1End'] scan1end = checkHourMin(scan1end) if scan1end.to_i >=0 setValue('end_time_a', scan1end) end scan2start = config['Scan2Start'] scan2start = checkHourMin(scan2start) if scan2start.to_i >=0 setValue('start_time_b', scan2start) end scan2end = config['Scan2End'] scan2end = checkHourMin(scan2end) if scan2end.to_i >=0 setValue('end_time_b', scan2end) end else Log4Ienso.log.P_INFO("Field scan not changed") end end #configchanged = 1 Log4Ienso.log.P_INFO("config changed " + configchanged.to_s ) end if config != nil Log4Ienso.log.P_INFO(" config is "+config.to_s) Log4Ienso.log.P_INFO(" name is "+ cameraname.to_s) Log4Ienso.log.P_INFO(" 2irelss is "+ wireless.to_s) Log4Ienso.log.P_INFO(" reportinterval "+ reportinterval.to_s) Log4Ienso.log.P_INFO(" overwrite "+ overwrite.to_s) end Log4Ienso.log.P_INFO("upload files is " + uploadfiles.to_s) Log4Ienso.log.P_INFO(" deleteall " + deleteall.to_s) Log4Ienso.log.P_INFO(" firmware " + firmware.to_s) if firmware != nil if trackingactive.to_s == nil trackingactive="na" end Log4Ienso.log.P_INFO(" trackingactive " + trackingactive.to_s) Log4Ienso.log.P_INFO("||| PARSING SUCCESS |||") $serverCMDSRcvd = true #used in daily check in when mode is never or wireless is set to off rescue Exception=>e Log4Ienso.log.P_INFO(e.stacktrace) ensure Log4Ienso.log.P_INFO("--- RETURN ------") return uploadfiles,configchanged,captureimage,deleteall,uploadfrequency, uploadloglevel,uploadlogurl,activatewifi,firmware,trackingactive,ret end return uploadfiles,configchanged,captureimage,deleteall, uploadfrequency, uploadloglevel,uploadlogurl,activatewifi,firmware,trackngactive,ret end #--------------------------------------------------------------------------------------------------------- # this function returns true if the length of the video is bigger than length # if not ,returns false def check_video_length(filename, length=15) #cmnd = "ffmpeg -i "+filename+" 2>&1 | grep 'Duration' " #dur=system(cmnd) begin dur=`ffmpeg -i #{filename} 2>&1 | grep "Duration"` puts dur dur=dur.split(",") t=dur[0].split(":") hr=t[1].to_i;min=t[2].to_i;sec=t[3].to_i; puts "dur=#{hr}:#{min}:#{sec}" duration = hr * 3600 + min * 60 + sec if duration > length return true else return false end rescue Exception => e Log4Ienso.log.P_ERR("Exception comm.send_char: #{e} ") return false end end #--------------------------------------------------------------------------------------------------------- # if the video is bigger than length , then cut it to 15 second and store in tmp folder # and return the name of the file # otherwise do nothing and return the filename def cut_video_length(filename, length=15) begin if check_video_length(filename, length) fn1= filename.split(".");puts fn1;fn=fn1[0]+'u.'+fn1[1]; puts fn `ffmpeg -i #{filename} -c copy -t 00:00:15 #{fn}` Log4Ienso.log.P_ERR( "video was cut to 15 seconds and saved as #{fn}") return fn else Log4Ienso.log.P_CLEAN( "NO need to cut video") return filename end rescue Exception => e Log4Ienso.log.P_ERR("Exception comm.send_char: #{e} ") return nil end end #--------------------------------------------------------------------------------------------------------- # this function returns true if the resolution of the video is same as resolution # if not ,returns false def check_video_resolution(filename, resolution='640x480') begin res=`ffmpeg -i #{filename} 2>&1 | grep "Video:"` puts "ffmpeg returned (in check_video_resolution) #{res}" if res.include? resolution return true else return false end rescue Exception => e Log4Ienso.log.P_ERR("Exception comm.send_char: #{e} ") return false end end #--------------------------------------------------------------------------------------------------------- # if the video scale is different than resolution , then change it and store in tmp folder # and return the name of the file # otherwise do nothing and return the filename def change_video_scale(filename, width=640, height=480) begin if !check_video_resolution(filename) # fn1= filename.split(".");puts fn1;fn=fn1[0]+'s.'+fn1[1]; puts fn fn1= filename.split(".");puts fn1;fn=fn1[0]+'s.mpeg'; puts fn `ffmpeg -i #{filename} -vf scale=640x480 #{fn}` Log4Ienso.log.P_ERR( "video was scaled to 640x480 and saved as #{fn}") return fn else Log4Ienso.log.P_CLEAN( "NO need to change video scale") return filename end rescue Exception => e Log4Ienso.log.P_ERR("Exception comm.send_char: #{e} ") return nil end end #------------------------------------------------------------------------------------------------------------------- def getHourMin(t) y = t.split(":") y[0] = "0"+y[0] if y[0].length == 1 y[1] = "0"+y[1] if y[1].length == 1 hm = y[0]+":"+y[1] puts(">>>>> #{hm}") return hm end def checkHourMin(t) t=t.strip y = t.split(":") return -1 if y.length < 2 return -1 if y[0].length > 2 return -1 if y[1].length > 2 return getHourMin(t) end def getAbsTime(t) y = t.split(":") return (y[0].to_i * 60 + y[1].to_i) end end if __FILE__ == $0 Log4Ienso.log.P_INFO("Starting image upload test") #861108030215163 #89302720405864485705 =begin Log4Ienso.log.P_INFO("checking wireless" ) wireless = config['WirelessEnabled'] wireless = 'on' if wireless == true wireless = 'off' if wireless == false if wireless != @env_wireless Log4Ienso.log.P_INFO("wrieless settings changed") setValue('wirless_on/off',wireless) @env_wireless = wireless else Log4Ienso.log.P_INFO("wrieless settings NOT changed") end Log4Ienso.log.P_INFO("end of wireless" ) reportinterval = config['ReportInterval'] # comm frequency quick, daily, weekly,never reportinterval = "daily" if reportinterval == "quick" setValue('report_interval',reportinterval) overwrite = "on" if overwrite == true overwrite ="off" if overwrite ==false overwrite = config['Overwrite'] setValue('overwrite',overwrite) mode = config['CaptureMode'] setValue('capture_mode', mode) capturecount = config['CaptureCount'] #no interface setValue('capture_count',capturecount) shutterspeed = config['ShutterSpeed'] #only night vision shutter speed setValue('shutter_speed', shutterspeed) imgresolution = config['ImageResolution'] setValue('image_resoluition',imgresolution) movieresolution = config['MovieResolution'] #terface setValue('movie_resoluition',movieresolution) movielength = config['MovieLength'] setValue('movie_length',movielength) pirdelay = config['PIRDelay'] #pir delay setValue('imaage_interval',pirdelay) pirsenstivity = config['PIRSensitivity'] #no equivalent on camera ledintensity = config['LEDIntensity'] setValue('led_power',ledintensity) showtimestamp = config['ShowTimestamp'] setValue('show_timestamp', showtimestamp) fieldscan = config['FieldScan'] setValue('field_scan', fieldscan) fieldscaninterval = config['ScanInterval'] #only interval a setValue('interval_a', fieldscaninterval.strip.chomp) setValue('interval_b', fieldscaninterval.strip.chomp) #for now both intervals same until zipit fix scan1start = config['Scan1Start'] setValue('start_time_a', scan1start) scan1end = config['Scan1End'] setValue('end_time_a', scan1end) scan2start = config['Scan2Start'] setValue('start_time_b', scan2start) scan2end = config['Scan2End'] setValue('start_time_b', scan2end) embedgps = config['EmbedGPS'] latitude = config['Latitude'] longitude = config['Longitude'] =end z = ZipItRestApi.new('861108033399600','89011703258074082046',"https://wtcbush:tipiz@dev2.wirelesstrophycam.com:8001","/var/wtc2.0/session.id", YAML.load(File.read("/opt/wtc2.0/src/wtc2_config_v0.0.2-a.yaml")).to_hashugar) z.register r=z.getCommands Log4Ienso.log.P_INFO(r) `echo #{r} > json.log` #z.parseServerCommand(r) uploadfiles,configchanged,captureimage,deleteall, uploadfrequency, uploadloglevel,uploadlogurl = z.parseServerCommand(r) puts("config changed is " + configchanged.to_s) storageused = 1024 storagesize = 1024*1024 battery = 50 latitude = 44.232 longitude = -79.344 rssi =2 #z.setConfigStatus(storageused,storagesize,battery,latitude,longitude,rssi) #Log4Ienso.log.P_NOTICE(uploadlogurl) #if uploadlogurl != nil # z.uploadLogFile(uploadlogurl) #end #f = z.getFirmWareManifest #puts(f) #filename ="./aa.jpeg" #cdn_url,cdn_host,id = z.getThumbnailCDN(filename) #Log4Ienso.log.P_INFO(cdn_url+ " " + cdn_host + " " + id.to_s) #z.uploadThumbnail(filename,cdn_url,cdn_host,id) end opt/wtc2.0/src/test/0000755000175200017520000000000013557057144014674 5ustar bushnellbushnellopt/wtc2.0/src/test/lcd_pc.rb0000644000175200017520000000437613557057144016457 0ustar bushnellbushnell require 'yaml' require 'optparse' require 'syslog/logger' require 'tk' class LcdScreen # Create an instance of the class. # params # - args: This parameter is meant to contain the application's config fileㅁ content. See config.yaml for details. See also Control for how to instantiate this class. @col = 0 @row = 0 def initialize(args={}) thr = Thread.new{ @line1 = TkVariable.new @line2 = TkVariable.new @line1.value = " " @line2.value = " " root = TkRoot.new { title "Hello, World!" minsize(400,100) } lbl = TkLabel.new(@root) do textvariable borderwidth 5 font TkFont.new('mono 40 bold') pack { padx 15 ; pady 15; side 'left' } end lb2 = TkLabel.new(@root) do textvariable borderwidth 5 font TkFont.new('mono 40 bold') pack { padx 15 ; pady 15; side 'left' } end lbl['textvariable'] = @line1 lb2['textvariable'] = @line2 Tk.mainloop } sleep(1) end # This initialization sequence is specified in the datasheet # Here, we will configure for 8bits def init_lcd @line1.value = " " @line2.value = " " end # Send a whole string def write_string(string) if @row == 1 str = @line1.value elsif @row == 2 str = @line2.value else raise("Invalid LCD row specification") end str1 = str[0..@col] str2 = str[@col + string.length .. -1] str = str1 + string + str2 if @row == 1 @line1.value = str elsif @row == 2 @line2.value = str else raise("Invalid LCD row specification") end sleep(0.0001) end def set_cursor_position(position) end def goto(row, col) @col = col - 1 @row = row end def clear @line1.value = " " @line2.value = " " end end opt/wtc2.0/src/test/shtest.rb0000644000175200017520000000001513557057144016527 0ustar bushnellbushnell system "ls" opt/wtc2.0/src/test/nmea.rb0000644000175200017520000000261413557057144016144 0ustar bushnellbushnell require 'nmea_plus' decoder = NMEAPlus::Decoder.new message = decoder.parse("$GPGLL,4916.45,N,12311.12,W,225444,A*00") # message data -- specific to this message type puts message.latitude # prints 49.27416666666666666666 puts message.longitude # prints -123.18533333333333333 puts message.fix_time # prints 22:54:44 puts message.valid? # prints true puts message.faa_mode # prints nil # metadata puts message.checksum_ok? # prints false -- because this checksum is made up puts message.original # prints "$GPGLL,4916.45,N,12311.12,W,225444,A*00" puts message.data_type # prints "GPGLL" -- what was specified in the message puts message.interpreted_data_type # prints "GLL" -- the actual container used # metadata that applies to multipart messages (also works for single messages) puts message.all_messages_received? # prints true puts message.all_checksums_ok? # prints false -- checksum is still made up # safer way to do what we did above if "GPGLL" == message.data_type # Alternately, if "GLL" == message.interpreted_data_type puts message.latitude # prints 49.27416666666666666666 puts message.longitude # prints -123.18533333333333333 puts message.fix_time # prints 22:54:44 puts message.valid? # prints true puts message.faa_mode # prints nil endopt/wtc2.0/src/test/test_ir_led.rb0000644000175200017520000000114413557057144017516 0ustar bushnellbushnell $LOAD_PATH.push File.expand_path("..", __FILE__) require './src/gpio' class IrLed def initialize(args={}) @led = Gpio.new(111) @led.direction='out' @led.clear @led_250 = Gpio.new(114) @led_250.direction='out' @led_250.clear end def ledEn() @led.set end def led250En() @led_250.set end def ledDis() @led.clear end def led250Dis() @led_250.clear end end # Test code... if $0 == __FILE__ ir = IrLed.new() ir.ledEn ir.led250En sleep(1) ir.ledDis ir.led250Dis end opt/wtc2.0/src/test/invoke.rb0000644000175200017520000000106513557057144016516 0ustar bushnellbushnell require 'io/console' def execute_process(path,name) pid = system("#{path}#{name} &") puts pid end def kill_process(name) pids = `pidof #{name}` pida = pids.split(' ') pida.each{|pid| Process.kill "USR2", pid.to_i } end def check_process(name) pids = `pidof #{name}` pida = pids.split(' ') pida.count > 0 end #system("/opt/wtc2.0/capture/bushnell-cam-capture") check_process("bushnell-cam-capture") #execute_process("/opt/wtc2.0/capture/", "bushnell-cam-capture") #sleep(1) #kill_process("bushnell-cam-capture")opt/wtc2.0/src/test/lte_tests/0000755000175200017520000000000013557057144016702 5ustar bushnellbushnellopt/wtc2.0/src/test/lte_tests/lte_connection_test.rb0000644000175200017520000000131313557057144023267 0ustar bushnellbushnellrequire 'lte.rb' options = { } optparse = OptionParser.new{|opt| opt.banner = 'This is the service template' opt.on('-cPATH', '--config=PATH', 'Location of the config file.'){|arg| raise("File #{arg} does not exit.") if not File.exists?(arg) i options[:config_path] = arg } } optparse.parse! begin options.assert_keys(:config_path) rescue puts("--config=path must be specified") exit(-1) end begini m=LteModem.new(YAML.load(File.read(options[:config_path])).to_hashugar) m.enable m.connect #cmd="echo at&d1 >/dev/ttyUSB2; echo ati > /dev/ttyUSB2" #system(cmd) rescue Exception => e puts("Exception: #{e}") puts(e.backtrace) end opt/wtc2.0/src/test/jsonTest.rb0000644000175200017520000000035213557057144017032 0ustar bushnellbushnellrequire 'json' exifTag = Hash.new() exifTag[:Make] = "IENSO" exifTag[:Model] = "WTC2.0" exifTag[:DateTimeOriginal] = "11" exifTag[:Manual] = {:ifdType => 1, :tagId => 132, :value => "1" }; json = JSON.generate(exifTag) puts jsonopt/wtc2.0/src/test/gpsTest.rb0000644000175200017520000000564213557057144016661 0ustar bushnellbushnell#!/usr/bin/env ruby # file: nmea_parser.rb require 'time' require 'date' class NMEAParser attr_reader :longitude, :latitude, :time def initialize(s=nil) parse(s) if s end alias lon longitude alias long longitude alias lat latitude def parse(raw_line) msgcode = raw_line[/^\$GP(\w+)/] return unless msgcode a = raw_line.split(',') case msgcode when /GGA/ _, raw_time, raw_lat, ns, raw_lon, ew = a @time, @latitude, @longitude = Time.parse(raw_time), decimalize(raw_lat, ns), decimalize(raw_lon, ew) # additional data captured # # Fix quality, Number of satellites being tracked, Horizontal dilution # of position, Altitude (Meters, above mean sea level), Height of # geoid, time in seconds since last DGPS update, DGPS station ID number @quality, @num_sat, @hdop, @altitude, @alt_unit, @height_geoid, @height_geoid_unit, @last_dgps, @dgps = a[6..-2] << a[-1][/^[^\*]+/] when /RMC/ _, raw_time, _, raw_lat, ns, raw_lon, ew = a @time, @latitude, @longitude = Time.parse(raw_time), decimalize(raw_lat, ns), decimalize(raw_lon, ew) # additional data captured # # Speed over the ground in knots, Track angle in degrees True, # Date, Magnetic Variation, @speed, @course = a[7..8] @date, @variation = Date.parse(a[9]), a[10] @var_direction = a[-1][/^[^\*]+/] when /VTG/ # data captured # True track made good (degrees), Magnetic track made good, # Ground speed (knots), Ground speed (Kilometers per hour) @track, @mag_track, @speed, @speed_kph = a.values_at(1,3,5,7) end self end def to_h() { time: @time, latitude: @latitude, longitude: @longitude, quality: @quality, num_sat: @num_sat, hdop: @hdop, altitude: @altitude, alt_unit: @alt_unit, height_geoid: @height_geoid, height_geoid_unit: @height_geoid_unit, last_dgps: @last_dgps, dgps: @dgps, course: @course, date: @date, variation: @variation, var_direction: @var_direction, track: @track, mag_track: @mag_track, speed: @speed, speed_kph: @speed_kph } end def to_struct() h = self.to_h Struct.new(*h.keys.map(&:to_sym)).new(*h.values).freeze end private def decimalize(raw_x, raw_nesw) nesw = {n: :+, e: :+, s: :-, w: :-} x = 0.method(nesw[raw_nesw.downcase.to_sym]).call(raw_x.to_f) degrees = (x / 100).to_i minutes = x - (degrees * 100.0) (degrees + (minutes / 60)).round(8) end end # Test code... if $0 == __FILE__ #s = '$GPGGA,045612.00,5554.95457,N,00306.82246,W,1,08,1.22,96.7,M,49.8,M,,*76' s = '$GPRMC,120543.000,V,0000.0000,N,00000.0000,E,000.0,000.0,280606,,,N*7D' np = NMEAParser.new(s) np.to_h puts np.time puts np.latitude puts np.longitude endopt/wtc2.0/src/test/gpiotest.rb0000644000175200017520000000146313557057144017063 0ustar bushnellbushnellrequire '../gpio' # EN: 108 # RW: 109 # RS: 110 # PWM: 124 # POWER: 125 # BLK: 71 # gpios_bus: # d0: 98 # d1: 99 # d2: 100 # d3: 101 # d4: 102 # d5: 103 # d6: 106 # d7: 107 gpio[0] = Gpio.new(108) gpio[1] = Gpio.new(109) gpio[2] = Gpio.new(110) gpio[3] = Gpio.new(124) gpio[4] = Gpio.new(125) gpio[5] = Gpio.new(71) gpio[6] = Gpio.new(98) gpio[7] = Gpio.new(99) gpio[8] = Gpio.new(101) gpio[9] = Gpio.new(102) gpio[10] = Gpio.new(103) gpio[11] = Gpio.new(106) gpio[12] = Gpio.new(107) for i in 0..12 gpio[i].direction = 'out' end while true do for i in 0..12 gpio[i].set end sleep(1) for i in 0..12 gpio[i].clear end sleep(1) endopt/wtc2.0/src/test/asc.rb0000644000175200017520000000013713557057144015770 0ustar bushnellbushnell port = "PE8" num = (port[1].ord - 'A'.ord) * 32 + port[2..5].to_i puts num puts port[2..5] opt/wtc2.0/src/test/irLedTest.rb0000644000175200017520000000155413557057144017125 0ustar bushnellbushnell#!/user/bin/ruby $LOAD_PATH.push File.expand_path("..", __FILE__) require './../gpio' def time_diff_milli(start, finish) (finish - start) * 1000.0 end # Test code... if $0 == __FILE__ led = Gpio.new(111) led.direction='out' led.clear led_250 = Gpio.new(114) led_250.direction='out' led_250.clear puts "Which led Do you turn on?" puts "1: IR LED 100 EN" puts "2: IR LED 250 EN" letReq = gets puts "How long Do you want Enable? please Answer milli second" timeReq = gets t1 = Time.now if (letReq == "1\n") led.set elsif(letReq == "2\n") led.set led_250.set else puts "error Num " + letReq return end trap("SIGINT") { throw :ctrl_c } catch :ctrl_c do begin sleep (timeReq.to_f/1000) rescue Exception puts "Not printed" end end led.clear led_250.clear t2 = Time.now msecs = time_diff_milli t1, t2 puts "\nEnable TIME : #{msecs} ms" end opt/wtc2.0/src/comm.rb0000644000175200017520000011627513557057144015211 0ustar bushnellbushnell $LOAD_PATH.push File.expand_path("..", __FILE__) require 'json' require 'slip' require 'timeout' require 'gpio' require 'thread' require 'keypad' require 'syslog/logger' require 'fileutils' require 'debug' # Stm32L01 Firmware Upgrade Class class Stm32_download ACK = 0x79 NACK = 0x1F PAGE_SIZE = 128 FLASH_START = 0x8000000 MAX_LENGTH = 256 def initialize(tty, firmware_path, send_char, recv_char) system("stty -F #{tty} raw cs8 -ignpar -cstopb -echo parenb -parodd -crtscts 115200") #@fifo = File.new("#{tty}", File::RDWR) #@fifo.sync = true @firmware = File.binread(firmware_path).unpack('C*') @send_char = send_char @recv_char = recv_char Log4Ienso.log.P_INFO("Stm32 download initial") #dump_bin(@firmware, 16) end def send_char(char) char = char & 0xff #@fifo.write([char].pack('C')) #F.write([char].pack('C')) @send_char.call(char) end def recv_char #c = @fifo.readpartial(1).bytes[0] #@F.write([c].pack('C')) @recv_char.call() end def dump_bin(bin, col) row = (bin.length / col) + 1 i = 0 buf = bin while i < row do str = "0x%08X | " % (i*col) buf[0..15].each{ |hex| str += "0x%02X, " % hex } buf = buf.drop(col) Log4Ienso.log.P_INFO(str) i += 1 end end def send_command( cmd ) recv = NACK ret = false if(cmd.instance_of? Fixnum) buf = [cmd, cmd ^ 0xff] elsif(cmd.instance_of? Array) buf = cmd checksum = 0 buf.each{ |val| checksum = (checksum ^ val) & 0xff } buf << (checksum & 0xff) #puts "Checksum #{(checksum & 0xff)}" end buf.each{|data| send_char(data) } begin Timeout::timeout(1){ recv = recv_char() } rescue Timeout::Error => e Log4Ienso.log.P_ERR(e) Log4Ienso.log.P_ERR(e.backtrace) end #puts "cmd reslut #{recv}" if(recv == 0x79) ret = true end ret end def recv_folowdata( nob = nil ) ret = [] if(nob == nil) nob = recv_char() + 1 end while nob != 0 do ret << recv_char() nob -= 1 end recv = recv_char() ret end def get_command() ret = send_command(0x00) if(ret == true) ret = recv_folowdata() Log4Ienso.log.P_NOTICE("version : 0x#{ret[0].to_s(16)}") ret.drop(1) Log4Ienso.log.P_INFO("support ID") ret.each{ |data| Log4Ienso.log.P_CLEAN("0x#{data.to_s(16)} ") } Log4Ienso.log.P_CLEAN("\n") end end def get_id() ret = send_command(0x00) if(ret == true) ret = recv_folowdata() Log4Ienso.log.P_INFO("pid : 0x#{ret[0].to_s(16)}#{ret[1].to_s(16)}") end ret end def read_memory(addr, len) if(len > MAX_LENGTH) Log4Ienso.log.P_INFO("a number of bytes must be less than #{MAX_LENGTH}") return false end ret = send_command(0x11) if(ret != true) return false; end a_addr = [(addr >> 24) & 0xff, (addr >> 16)&0xff, (addr >> 8)&0xff, addr&0xff] ret = send_command(a_addr) if(ret != true) return false; end ret = send_command(len - 1) if(ret != true) return false; end ret = [] while len != 0 do recv = recv_char() ret << recv len -= 1 end ret end def write_memory(addr, buf) #puts "Write memory addr [%08X] len[#{buf.length}]" % addr if(buf.length > MAX_LENGTH) Log4Ienso.log.P_INFO("a number of bytes must be less than #{MAX_LENGTH}") return false end ret = send_command(0x31) if(ret != true) return false; end a_addr = [(addr >> 24) & 0xff, (addr >> 16)&0xff, (addr >> 8)&0xff, addr&0xff] ret = send_command(a_addr) if(ret != true) return false; end buf = [buf.length - 1] + buf ret = send_command(buf) if(ret != true) return false; end ret end def erase_memory( start_page, num_of_page ) Log4Ienso.log.P_INFO("Erase Memory start #{start_page} num #{num_of_page}") recv = 0 ret = send_command(0x44) idx = num_of_page if(ret != true) return false; end buf = [((num_of_page - 1) >> 8) & 0xff, (num_of_page - 1) & 0xff] while idx != 0 do buf << (( start_page >> 8 ) & 0xff) buf << (start_page & 0xff) idx -= 1 start_page += 1 end ret = send_command(buf) end def readout_protect(on_off) recv = 0 if(on_off == false) ret = send_command(0x92) else ret = send_command(0x82) end ret = false begin Timeout::timeout(1){ recv = recv_char() } rescue Timeout::Error => e Log4Ienso.log.P_ERR(e) Log4Ienso.log.P_ERR(e.backtrace) end Log4Ienso.log.P_INFO("readout_protect #{recv}") if(recv == 0x79) ret = true end end def write_protect(on_off) recv = 0 if(on_off == false) ret = send_command(0x73) else ret = send_command(0x63) end ret = false begin Timeout::timeout(1){ recv = recv_char() } rescue Timeout::Error => e Log4Ienso.log.P_ERR(e) Log4Ienso.log.P_ERR(e.backtrace) end Log4Ienso.log.P_INFO("write_protect #{recv}") if(recv == 0x79) ret = true end end def go(addr) ret = send_command(0x21) if(ret != true) return false; end a_addr = [(addr >> 24) & 0xff, (addr >> 16)&0xff, (addr >> 8)&0xff, addr&0xff] ret = send_command(a_addr) if(ret != true) return false; end ret end def download_firmware(reset_gpio) ret = true Log4Ienso.log.P_INFO("Download firmware length [#{@firmware.length}]") system("echo 1 > /sys/power/aw_pm/sleep_indicate") reset = Gpio.new(reset_gpio) reset.direction = 'out' reset.set sleep(0.5) reset.clear reset.direction = 'in' sleep(0.5) recv = nil send_char(0x7f) begin Timeout::timeout(0.5){ recv = recv_char() } rescue Timeout::Error => e Log4Ienso.log.P_ERR(e) Log4Ienso.log.P_ERR(e.backtrace) ret = false end if(ret == true) #get_command() #get_id() #write_protect(false) #sleep(1) num_of_page = (@firmware.length/PAGE_SIZE) + 1 erase_memory(0, num_of_page) idx = 0 while idx < @firmware.length do write_buf = @firmware[idx..(idx + (PAGE_SIZE - 1))] write_memory(FLASH_START + idx, write_buf) read_buf = read_memory(FLASH_START + idx, write_buf.length) if(write_buf === read_buf) #puts "Verify OKAY" else ret = false break end idx += PAGE_SIZE end Log4Ienso.log.P_NOTICE("Download SUCCESS") end system("echo 0 > /sys/power/aw_pm/sleep_indicate") ret end end # Communication Class with M0 class Comm include EventSource ERR_RETCOUNT = 10 # * *Args* : # - config -> configuration value for this class # - initial_value -> initial value for M0 def initialize(config, initial_value) @comm_err = 0; @config = config @log = Syslog::Logger.new(@config.log_name) @initial_value = initial_value @fifo = File.new(@config.tty, File::RDWR) @fifo.sync = true #@F=File.new("log_uart_comm.dat", File::RDWR | File::CREAT) #@F.sync = true system("stty -F #{@config.tty} raw cs8 -ignpar -cstopb -echo -parenb -crtscts 115200") @upgrade_flag = false @temp = 0 @mutex = Mutex.new #resetM0() initial_M0() @interrupt = Button.new(@config.gpio_int.to_hash()) @interrupt.add_listener(self) @interrupt.start() @interrupt_mask = true @mutex_int_mask = Mutex.new end # Called whenever a button is pressed # params: # - event: the button information including up/down state def handle_event(event, data = nil) #puts event if(@upgrade_flag == true) Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} _____________ WARNING:_____________during upgrade handle_event was ignored ") return end @mutex_int_mask.synchronize{ Log4Ienso.log.P_YELLOW("#{Time.now.strftime("%H:%M:%S.%L")} [Ruby - M0] RX : Received INT from M0 #{@config.gpio_int.gpio}\n") ret = check_wakeup_reason(1) if( @interrupt_mask == false ) notify('comm/interrupted', ret) if(ret != nil) else Log4Ienso.log.P_ERR("#{Time.now.strftime("%H:%M:%S.%L")} _____________ WARNING: _____________ comm/interrup was ignored BECAUSE OF interrupt masked") $pir_confirmation_flag = false if $pir_confirmation_flag if( ret[:pir] == true || ret[:field_scan] == true || ret[:field_scanb] == true ) # send end of video/pic if pir send_vid_pic_end( ) end if (ret[:accelerometer] == true) notify('comm/interrupt_accelerometer', ret) Log4Ienso.log.P_INFO("_____________accelerometer sent to display on while interrupt masked ") end if (ret[:a83_awake] == true) notify('comm/interrupt_accelerometer', ret) Log4Ienso.log.P_INFO("_____________a83 wakeup sent to display on while interrupt masked ") end end } end # it will be mask any interrupt form M0 def interrupt_mask(mask = true) @mutex_int_mask.synchronize{ @interrupt_mask = mask } end def set_upgrade_flag (flag = true) @upgrade_flag = flag @fifo.close end def send_char(char) begin @fifo.write([char].pack('C')) rescue Exception => e Log4Ienso.log.P_ERR("Exception comm.send_char: #{e} ") end end def recv_char c = nil begin c = @fifo.readpartial(1).bytes[0] rescue Exception => e Log4Ienso.log.P_ERR("Exception comm.recv_char: #{e} ") end c end # Interrupt reason check # * *Raises* : # - CommunicationError -> If failed communication between A83 and M0 def check_wakeup_reason (resume = 0) remove_reason_flag = true #send_end_pic_flag = false ret = {} packet1 = [1, 0, 0] packet = [1, 0, 0, 0] cmnd = "check_wakeup_reason" packet = send_receive2(packet1, cmnd) if((packet != nil) && (packet[1].is_a? Numeric)) @temp = packet[3] if (@temp > 127) @temp -= 256 end ret = { :pir => false, :day => false, :night => false, :photocell => false, :power_button => false, :a83_awake => false, :field_scan => false, :sms => false, :field_scanb => false,:accelerometer => false,:theftmode => false,:dailyalert => false, :send_pic_interval => false } if (packet[1] & 0x01) > 0 if resume == 0 if (packet[2] & 0x80) > 0 Log4Ienso.log.P_MAGENTA("#{Time.now.strftime("%H:%M:%S.%L")} !!! it's pir from pmic and not fake !!!\n") ret[:pir] = true else Log4Ienso.log.P_YELLOW("#{Time.now.strftime("%H:%M:%S.%L")} !!! it's pir from pmic but IT'S FAKE and ignored !!!\n") get_t1() get_t2() get_t3() $send_end_pic_flag = true end elsif resume == 1 ret[:pir] = true remove_reason_flag = false $pir_confirmation_flag = true Log4Ienso.log.P_MAGENTA("#{Time.now.strftime("%H:%M:%S.%L")} !!! it's pir from m0 so not remove reason and wait for confirmation!!!\n") else end end if resume == 2 if (packet[2] & 0x80) > 0 Log4Ienso.log.P_MAGENTA("#{Time.now.strftime("%H:%M:%S.%L")} !!! it's pir from m0 and not fake !!!\n") ret[:pir] = true else Log4Ienso.log.P_YELLOW("#{Time.now.strftime("%H:%M:%S.%L")} !!! it's pir from m0 but IT'S FAKE and ignored !!!\n") #get_t1() #get_t2() #get_t3() end end if (packet[1] & 0x02) > 0 then ret[:day] = true end if (packet[1] & 0x04) > 0 then ret[:night] = true end if (packet[1] & 0x08) > 0 then ret[:photocell] = true end if (packet[1] & 0x10) > 0 then ret[:field_scan] = true end if (packet[1] & 0x20) > 0 then ret[:sms] = true end if (packet[1] & 0x40) > 0 then ret[:field_scanb] = true end if (packet[1] & 0x80) > 0 then ret[:accelerometer] = true end pword = packet[2] << 8; pword = pword + packet[1] if (pword & 0x100) == 0x100 ret[:theftmode] = true; Log4Ienso.log.P_NOTICE(">>> Theft mode detected valus as <<<" + pword.to_s(2)) end if (pword & 0x200) == 0x200 ret[:send_pic_interval] = true; Log4Ienso.log.P_NOTICE(">>> send_pic_interval detected <<<") end if (pword & 0x400) == 0x400 ret[:a83_awake] = true; Log4Ienso.log.P_NOTICE(">>> Gps Awake <<<") end if (pword & 0x800) == 0x800 ret[:dailyalert] = true; Log4Ienso.log.P_NOTICE(">>> Daily alert detected <<<") end if((ret[:day] == true) && (ret[:night] == true) ) ret[:err_ir] = true; end # During sleep mode, if user press power button more than 1 sec, PMIC register is not set. So we need below code. if((ret[:pir] == false ) && (ret[:day] == false) && (ret[:night] == false) && (ret[:photocell] == false) && (ret[:field_scan] == false) && (ret[:sms] == false) && (ret[:field_scanb] == false) && (ret[:accelerometer] == false) && (ret[:theftmode] == false) && (ret[:dailyalert] == false)) #ret[:power_button] = true; Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} ---power button = true [Ruby - M0] RX : packet[1] = 0x#{packet[1].to_s(16)}") end #Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} [Ruby - M0] RX : packet[1] = 0x#{packet[1].to_s(16)}") Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} [Ruby - M0] RX : packet[1] = 0x#{packet[1].to_s(16)}, packet[2] = 0x#{packet[2].to_s(16)},packet[3] = #{packet[3]} ") $trigger="" if packet[1] != 0 Log4Ienso.log.P_CLEAN(" ==> #{Time.now.strftime("%H:%M:%S.%L")} ") if (ret[:pir] == true) Log4Ienso.log.P_MAGENTA(" PIR = #{ret[:pir]}") $trigger="PIR" end if (ret[:day] == true) Log4Ienso.log.P_CLEAN(" DAY = #{ret[:day]}") $trigger="DAY" end if (ret[:night] == true) Log4Ienso.log.P_CLEAN(" NIGHT = #{ret[:night]}") $trigger="NIGHT" end if (ret[:photocell] == true) Log4Ienso.log.P_CLEAN(" PHOTOCELL = #{ret[:photocell]}") $trigger="PHOTOCELL" end if (ret[:field_scan] == true) Log4Ienso.log.P_CLEAN(" FIELD SCAN = #{ret[:field_scan]}") $trigger="FIELDSCAN A" end if (ret[:sms] == true) Log4Ienso.log.P_CLEAN(" SMS = #{ret[:sms]}") $trigger="SMS" end if (ret[:field_scanb] == true) Log4Ienso.log.P_CLEAN(" FIELD SCANB = #{ret[:field_scanb]}") $trigger="FIELDSCAN B" end if (ret[:accelerometer] == true) Log4Ienso.log.P_CLEAN(" ACCELEROMETER = #{ret[:accelerometer]}") $trigger="ACCELEROMETER" end if (ret[:power_button] == true) Log4Ienso.log.P_CLEAN(" PWR BUTTON = #{ret[:power_button]}") $trigger="PWR BUTTON" end if (ret[:theftmode] == true) Log4Ienso.log.P_CLEAN("THEFTMODE = #{ret[:theftmode]}") $trigger="THEFT MODE" end if (ret[:dailyalert] == true) Log4Ienso.log.P_CLEAN(" DAILY ALERT = #{ret[:dailyalert]}") $trigger="DAILY ALERT" end if (ret[:a83_awake] == true) Log4Ienso.log.P_CLEAN(" A83 AWAKE = #{ret[:a83_awake]}") $trigger="A83 AWAKE" end Log4Ienso.log.P_CLEAN("\n") end remove_wakeup_reason() if remove_reason_flag #if send_end_pic_flag # send_vid_pic_end() # send_end_pic_flag = false #end else ret = {:err_comm => true} end ret end # Set Photocell value to judge between day and night # * *Args* : # - val -> want to setting # * *Returns* : # - setted photocell judgement value # * *Raises* : # - CommunicationError -> If failed communication between A83 and M0 def set_photocell(val) ret = nil packet = [0x02, val.to_i & 0xff, (val.to_i>>8) & 0xff] cmnd = "set_photocell val=#{val.to_i}" packet = send_receive2(packet, cmnd) if(packet != nil) ret = packet[2] << 8 ret = ret + packet[1] end change_initial_value(0x02, val) ret end def get_temp() @temp end # * *Returns* : # - Photocell value from M0 # * *Raises* : # - CommunicationError -> If failed communication between A83 and M0 def get_photocell() ret = 0 packet = [0x03, 0, 0] cmnd = "get_photocell" packet = send_receive2(packet, cmnd) if(packet != nil) ret = packet[2] << 8; ret = ret + packet[1] Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} [Ruby - M0] RX : get_photocell val=#{ret}") end ret end def enable_quectel_slow_clock() ret = 0 packet = [0x19, 1] cmnd = "quectel slow clock" packet = send_receive2(packet, cmnd) if(packet != nil) ret = packet[0] << 8; ret = ret + packet[1] end ret end def a83_sleeping() ret = 0 packet = [0x19, 0] cmnd = "A83 is going to sleep" packet = send_receive2(packet, cmnd) if(packet != nil) ret = packet[0] << 8; ret = ret + packet[1] end ret end def a83_power_down() ret = 0 packet = [0x18, 0] cmnd = "a83 shuting down" packet = send_receive2(packet, cmnd) if(packet != nil) ret = packet[0] << 8; ret = ret + packet[1] end ret end def start_board_testing() ret = 0 packet = [0x17, 1] cmnd = "start_board_testing" packet = send_receive2(packet, cmnd) if(packet != nil) ret = packet[0] << 8; ret = ret + packet[1] end ret end def stop_board_testing() ret = 0 packet = [0x17, 0] cmnd = "stop_board_testing" packet = send_receive2(packet, cmnd) if(packet != nil) ret = packet[0] << 8; ret = ret + packet[1] end ret end def pir_board_testing() ret = 0 packet = [0x17, 2] cmnd = "pir_board_testing" packet = send_receive2(packet, cmnd) if(packet != nil) ret = packet[0] << 8; ret = ret + packet[1] end ret end def accelerometer_board_testing() ret = 0 packet = [0x17, 4] cmnd = "accelerometer_board_testing" packet = send_receive2(packet, cmnd) if(packet != nil) ret = packet[0] << 8; ret = ret + packet[1] end ret end def adc_board_testing() ret = 0 packet = [0x17, 8] cmnd = "adc_board_testing" packet = send_receive2(packet, cmnd) if(packet != nil) ret = packet[0] << 8; ret = ret + packet[1] end ret end def disable_heart_bit() ret = 0 packet = [0x11, 0x00] cmnd = "disable heart bit" packet = send_receive2(packet, cmnd) if(packet != nil) ret = packet[0] << 8; ret = ret + packet[1] Log4Ienso.log.P_NOTICE("========+++++++++++++++++++=======") end ret end def send_heart_bit(time = 60) ret = 0 #time10 = time / 10 packet = [0x0a, 0x55, 0xaa, time & 0xff] cmnd = "" packet = send_receive2(packet, cmnd) if(packet != nil) ret = packet[0] << 8; ret = ret + packet[1] Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")}====-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_--_====") end ret end def get_reset_counter() ret1 = ret2 = 0 packet = [0x12, 0x00] cmnd = "get reset counter" packet = send_receive2(packet, cmnd) if(packet != nil) ret1 = packet[1] ret2 = packet[2] Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} [Ruby - M0] RX : send get reset counter=#{packet[0]} , #{packet[1]} , #{packet[2]}") end return ret1,ret2 end def lte_off() ret = 0 packet = [0x16, 0x00] cmnd = "send lte off" packet = send_receive2(packet, cmnd) ret = packet[1] if packet != nil ret end def lte_on() ret = 0 packet = [0x16, 0x01] cmnd = "send lte on" packet = send_receive2(packet, cmnd) ret = packet[1] if packet != nil ret end def power_off_on() ret = 0 packet = [0x16, 0x02] cmnd = "power off then on" packet = send_receive2(packet, cmnd) ret = packet[1] if packet != nil ret end def get_acclerometer() ret = 0 packet = [0x07, 0, 0] cmnd = "get_accelerometer" packet = send_receive2(packet, cmnd) if(packet != nil) ret = packet[2] << 8; ret = ret + packet[1] end ret end # getting Day or Night flag form M0 # * *Returns* : # - Day(1) or Night(1) # * *Raises* : # - CommunicationError -> If failed communication between A83 and M0 def get_day_night() ret = nil packet = [0x05, 0, 0] cmnd = "get_day_night" packet = send_receive2(packet, cmnd) if(packet != nil) ret = packet[1] Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} [Ruby - M0] RX : get_day_night val=#{ret} (0:night, 1:day)") end ret end # Set Trigger time # * *Args* : # - val -> want to setting # * *Returns* : # - setted Trigger time # * *Raises* : # - CommunicationError -> If failed communication between A83 and M0 def set_picdelaytime(val) ret = nil packet = [0x06, val.to_i & 0xff, (val.to_i>>8) & 0xff] cmnd = "set_picdelaytime #{val.to_i}" packet = send_receive2(packet, cmnd) if(packet != nil) ret = packet[2] << 8; ret = ret + packet[1] end change_initial_value(0x06, val) ret end def int_to_bcd_bytes(int) h10 = ((int / 10) & 0x0f) << 4 h1 = (int % 10) & 0x0f hr = h10 | h1 hr end def set_m0_rtc_time() ret = nil sec=`date +%S`; sec=sec.to_i; sec_bcd = int_to_bcd_bytes(sec); #get the second min=`date +%M`; min=min.to_i; min_bcd = int_to_bcd_bytes(min); #get the minute hr=`date +%H`; hr=hr.to_i; hr_bcd = int_to_bcd_bytes(hr); #get the hour packet = [0x08, hr_bcd & 0xff, min_bcd & 0xff, sec_bcd & 0xff ] cmnd ="set_m0_rtc time frame packet=#{packet}" packet = send_receive2(packet, cmnd) ret = packet[1] if packet != nil ret end def set_m0_rtc_date() ret = nil day=`date +%u`; day=day.to_i; #get day in number mon=1, sun=7 date=`date +%x`; date=date.split('/');mm=date[0];dd=date[1];yy=date[2];mm=mm.to_i;dd=dd.to_i;yy=yy.to_i; mm_bcd = int_to_bcd_bytes(mm); dd_bcd = int_to_bcd_bytes(dd); yy_bcd = int_to_bcd_bytes(yy); packet = [0x0b, yy_bcd & 0xff, mm_bcd & 0xff, dd_bcd & 0xff, day & 0xff ] cmnd ="set_m0_rtc date frame packet=#{packet}" packet = send_receive2(packet, cmnd) ret = packet[1] if packet != nil ret end def set_m0_rtc() ret = nil ret = set_m0_rtc_time ret = set_m0_rtc_date end def set_m0_pir_mode(packet) ret = nil cmnd ="set_m0_pir_mode packet=#{packet}" packet = send_receive2(packet, cmnd) ret = packet[1] if packet != nil ret end def set_m0_time_zone(packet) ret = nil cmnd ="set_m0_rtc time zone packet=#{packet}" packet = send_receive2(packet, cmnd) ret = packet[1] if packet != nil ret end def set_m0_field_scan(packet) ret = nil cmnd ="set_m0_field_scan packet=#{packet}" packet = send_receive2(packet, cmnd) ret = packet[1] if packet != nil ret end def get_mo_revision() ret = nil packet = [0x63, 0, 0] #message id =0x63=99 cmnd ="[Ruby - M0] TX : get_m0_revision" packet = send_receive2(packet, cmnd) if(packet != nil) ret = "#{packet[1]}.#{packet[2] }.#{packet[3] }" Log4Ienso.log.P_INFO("[Ruby - M0] RX : get_m0_revision val=#{ret} ") end ret end def set_image_type (img_type, vid_length = 0) ret = nil i1 = 1 if(img_type == 'image') i1 = 0 end packet = [0x0c, i1 & 0xff, vid_length & 0xff] #message id = 0x0c = 12 cmnd ="[Ruby - M0] TX : set_m0_image type" packet = send_receive2(packet, cmnd) if(packet != nil) ret = " #{packet[1]}.#{packet[2] }.#{packet[3] }" Log4Ienso.log.P_INFO("[Ruby - M0] RX : set_m0__image type val=#{ret} ") end ret end def set_pir_sensitivity (level = 0) ret = nil if (level == 3) level = 4 end packet = [0x10, level & 0xff] #message id = 0x10 = 16 cmnd = "[Ruby - M0] TX : set_m0_pir sensitivity #{packet}" packet = send_receive2(packet, cmnd) ret = packet[1] if packet != nil ret end def wakeup_a83_timer (status = 0, delay = 0) ret = nil packet = [0x1b, status & 0xff, delay & 0xff] #message id = 0x1b = 27 cmnd = "[Ruby - M0] TX : wakeup_a83_timer #{packet}" packet = send_receive2(packet, cmnd) ret = packet[1] if packet != nil ret end def send_vid_pic_end( ) ret = nil packet = [0x1c, 0x00, 0x00] #message id = 0x1c = 28 cmnd = "[Ruby - M0] TX : send_video/picture end #{packet}" packet = send_receive2(packet, cmnd) ret = packet[1] if packet != nil ret end def ignore_pir( ) ret = nil packet = [0x1d, 0x01] #message id = 0x1d = 29, 1 cmnd = "[Ruby - M0] TX : ignore pir trigger #{packet}" packet = send_receive2(packet, cmnd) ret = packet[1] if packet != nil ret end def resume_pir( ) ret = nil packet = [0x1d, 0x00] #message id = 0x1d = 29, 0 cmnd = "[Ruby - M0] TX : resume pir trigger #{packet}" packet = send_receive2(packet, cmnd) ret = packet[1] if packet != nil ret end # * *Returns* : # - Battery level from M0 # * *Raises* : # - CommunicationError -> If failed communication between A83 and M0 def get_battery_level() ret = 0 if(@upgrade_flag == true) Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} _____________ WARNING:_____________during upgrade get_battery was ignored ") return ret end packet = [0xF, 0, 0] cmnd = "[Ruby - M0] TX : get_battery_level" packet = send_receive2(packet, cmnd) ret = packet[1] if packet != nil ret end def set_default_settings() ret = 0 packet = [0x13, 0, 0] cmnd = "[Ruby - M0] TX : set_default_settings" packet = send_receive2(packet, cmnd) ret = packet[1] if packet != nil ret end # Upgrade M0 firmware # * *Args* : # - path -> M0 Firmware Bin file path def download_firmware(path) # This class will change uart speed and parety bit dwon = Stm32_download.new(@config.tty, path, method(:send_char), method(:recv_char)) dwon.download_firmware(@config.gpio_reset) # UART setting restore system("stty -F #{@config.tty} raw cs8 -ignpar -cstopb -echo -parenb -crtscts 115200") resetM0() end # this is enabled by the user remotely (website) # for testing there is menu option under /network/diagnostics # enabling theft mode does not start the tracking, the camera has to mover / turned around def enable_theft_mode Log4Ienso.log.P_INFO("Camera enabled for theft mode tracking") packet = [0x15,0x01,0x00] packet = send_receive(packet) @log.error("#{Time.now.strftime("%H:%M:%S.%L")} M0 doesn't Receive") if(packet == nil) if((packet != nil)) ret = " #{packet[1]}.#{packet[2] } }" Log4Ienso.log.P_INFO("[Ruby - M0] RX : enable theft mode=#{ret} ") end #`touch /var/wtc2.0/trackingon` end # on power cycle, the camera needs to know if theft mode tracking is on def check_theft_mode_on_reboot #if File.exist?('/var/wtc2.0/trackingon') Log4Ienso.log.P_INFO("Camera in theft mode tracking on reboot") packet = [0x15,0x01,0x01] packet = send_receive(packet) @log.error("#{Time.now.strftime("%H:%M:%S.%L")} M0 doesn't Receive") if(packet == nil) if((packet != nil)) ret = " #{packet[1]}.#{packet[2] } }" Log4Ienso.log.P_INFO("[Ruby - M0] RX : enable theft mode on reboot=#{ret} ") end #end end # like enable, the disable command is also remotely provided def disable_theft_mode packet = [0x15,0x00,0x00] packet = send_receive(packet) @log.error("#{Time.now.strftime("%H:%M:%S.%L")} M0 doesn't Receive") if(packet == nil) if((packet != nil)) ret = " #{packet[1]}.#{packet[2] } }" Log4Ienso.log.P_INFO("[Ruby - M0] RX : disable theft mode=#{ret} ") end Log4Ienso.log.P_NOTICE(">>> Theft mode disabled <<<") #`rm /var/wtc2.0/trackingon` end # Test function that siwtchs off power to A83 and only keeps Quectel powered up def force_turn_on packet = [0x1a,0x00,0x00] packet = send_receive(packet) @log.error("#{Time.now.strftime("%H:%M:%S.%L")} M0 doesn't Receive") if(packet == nil) if((packet != nil)) ret = " #{packet[1]}.#{packet[2] } }" Log4Ienso.log.P_INFO("[Ruby - M0] RX : force turn on=#{ret} ") end Log4Ienso.log.P_NOTICE(">>> Force turn on <<<") end def get_t1() ret = nil packet = [0x20, 0, 0] cmnd = "get_t1" packet = send_receive2(packet, cmnd) if(packet != nil) ret = packet[2] << 8; ret = ret + packet[1] Log4Ienso.log.P_YELLOW("#{Time.now.strftime("%H:%M:%S.%L")} [Ruby - M0] RX : get_t1 val=#{ret}\n ") end ret end def get_t2() ret = nil packet = [0x21, 0, 0] cmnd = "get_t2" packet = send_receive2(packet, cmnd) if(packet != nil) ret = packet[2] << 8; ret = ret + packet[1] Log4Ienso.log.P_YELLOW("#{Time.now.strftime("%H:%M:%S.%L")} [Ruby - M0] RX : get_t2 val=#{ret}\n ") end ret end def get_t3() ret = nil packet = [0x22, 0, 0] cmnd = "get_t3" packet = send_receive2(packet, cmnd) if(packet != nil) ret = packet[2] << 8; ret = ret + packet[1] Log4Ienso.log.P_YELLOW("#{Time.now.strftime("%H:%M:%S.%L")} [Ruby - M0] RX : get_t3 val=#{ret}\n ") end ret end def set_trigger_timing(time = 0) ret = nil packet = [0x1f, time & 0xff] cmnd = "[Ruby - M0] TX : set_m0_trigger timing #{packet}" packet = send_receive2(packet, cmnd) if(packet != nil) ret = packet[1] Log4Ienso.log.P_YELLOW("#{Time.now.strftime("%H:%M:%S.%L")} [Ruby - M0] RX : set_triffer timing return =#{ret}\n ") end ret end private def remove_wakeup_reason( ) ret = nil packet = [0x04,0,0] cmnd = "remove_wakeup_reason" packet = send_receive2(packet, cmnd) #Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} [Ruby - M0] TX : remove_wakeup_reason") #packet = send_receive(packet) #Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} [Ruby - M0] RX : remove_wakeup_reason ack=#{packet}") #@log.error("#{Time.now.strftime("%H:%M:%S.%L")} M0 doesn't Receive") if(packet == nil) end def send_receive2(packet, cmnd = "") try_cntr = 0 ret = nil while try_cntr < 2 do Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} [Ruby - M0] TX : #{cmnd}") ret = send_receive(packet) if((ret != nil) && (ret.size >= 3)) if (ret[0] == packet[0]) Log4Ienso.log.P_NOTICE("[Ruby - M0] RX : #{cmnd} return OK= packet[0]=#{ret[0]}, packet[1]=#{ret[1]}, packet[2]=#{ret[2]},packet[3]=#{ret[3] }") break else try_cntr += 1 Log4Ienso.log.P_ERR("[Ruby - M0] RX : #{cmnd} return WRONG RESPONSE TRIED NO=#{try_cntr} ,RESPONSE=#{ret}") ret = nil begin ret = Timeout::timeout(0.005){ recv_packet } rescue Timeout::Error => e Log4Ienso.log.P_ERR(e) Log4Ienso.log.P_ERR(e.backtrace) ret = nil end if ( ret == nil) Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} [Ruby - M0] Note: No buffer detected ") next else if (ret[0] == packet[0]) && (ret.size >= 3) Log4Ienso.log.P_NOTICE("[Ruby - M0] RX : buffered #{cmnd} return OK= packet[0]=#{ret[0]}, packet[1]=#{ret[1]}, packet[2]=#{ret[2]},packet[3]=#{ret[3] }") break else Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} [Ruby - M0] Note: buffer detected but not correct Response so retry!!! ") ret = nil next end end end end end ret end # Send packet and waiting until receive response # * *Args* : # -packet -> m0 communication packet # * *Returns* : # - received data # * *Raises* : # - CommunicationError -> If failed communication between A83 and M0 def send_receive(packet) recv_cmd = nil error = false packet = packet.pack("C*") if( @upgrade_flag == true) Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} _____________ WARNING:_____________during upgrade send_receive was ignored ") return packet end i = 0 @comm_err += 1; @mutex.synchronize{ for i in 0..ERR_RETCOUNT begin if i > 0 Log4Ienso.log.P_WARN("#{Time.now.strftime("%H:%M:%S.%L")} [Ruby - M0] TX : ### Resend packet #{packet}") end send_packet(packet) recv_cmd = Timeout::timeout(1.0){ recv_packet } if ( recv_cmd != nil) break end rescue Timeout::Error => e @log.error("Timedout waiting. Retrying...") Log4Ienso.log.P_ERR("Comm Timeout #{i} !!!") #Log4Ienso.log.P_ERR(e.backtrace) error = true end end } #if( (@upgrade_flag == false) && (error == true) && (i >= ERR_RETCOUNT) && (@comm_err <= 1)) if( (@upgrade_flag == false) && (error == true) && (i >= ERR_RETCOUNT) ) @log.error("Communication ERROR #{@comm_err}") resetM0() initial_M0() end @comm_err -=1 recv_cmd end def resetM0() Log4Ienso.log.P_ERR("Reset M0 COMMUNICATION ERROR!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") @log.error( "Reset M0 COMMUNICATION ERROR!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ") system("echo 0 > /sys/power/aw_pm/sleep_indicate") reset = Gpio.new(@config.gpio_reset) reset.direction = 'out' reset.set sleep(0.2) reset.clear reset.direction = 'in' sleep(0.3) system("echo 1 > /sys/power/aw_pm/sleep_indicate") sleep(1) end # Initialize M0 setting value def initial_M0() Log4Ienso.log.P_INFO("initial_M0") if(@initial_value != nil) @initial_value.each{ |cmd| case cmd[0] when 0x02 set_photocell(cmd[1]) when 0x06 set_picdelaytime(cmd[1]) end } notify('comm/initial') end end def change_initial_value(req_cmd, value) @initial_value.each{ |cmd| if(cmd[0] == req_cmd) cmd[1] = value end } end end if $0 == __FILE__ def send_char(char) @fifo.write([char].pack('C')) #F.write([char].pack('C')) end def recv_char c = @fifo.readpartial(1).bytes[0] #@F.write([c].pack('C')) c end @fifo = File.new('/dev/ttyS4', File::RDWR) @fifo.sync = true dwon = Stm32_download.new('/dev/ttyS4', '/media/photos/wtc_m0_E08.bin', method(:send_char), method(:recv_char)) dwon.download_firmware('PE08') end opt/wtc2.0/src/gnns-update.sh0000755000175200017520000000754313557057144016512 0ustar bushnellbushnell#!/bin/sh ################################################### # Quectel Linux script to update the GNSS with # latest ephermis data # The script does the following# a) Download the latest ephermis data # b) Inject the utc time and ephermis file into gnss # The file can be downloaded over FTP or HTTP # or uploaded from the file system into quectel ################################################### mode="FTP" ftp_server=$1 #"ftp.ienso.com" ftp_user=$2 #"bushnell.ienso.com" ftp_password=$3 #"bushnellienso" #set ftp password if using ftp apn=$4 #"m2minternet.apn" for Rogers pdp=$5 #"1" Rogers utctime=$6 #"$(date -u +%Y/%m/%d,%T)" #system time should be utc of format 2018/05/30,16:26:37 echo $utctime path="http://xtrapath1.izatcloud.net/xtra2.bin" #set slow clock if [ -e /dev/ttyUSB3 ] then echo "Ports available" echo at > /dev/ttyUSB3 sleep 0.3 if [ $mode = "FTP" ] then echo AT+QICSGP=1,1,\"$apn\",\"\",\"\",$pdp > /dev/ttyUSB3 sleep 0.3 echo AT+QIACT=1 > /dev/ttyUSB3 sleep 0.3 #echo "checking if ip address availabile" echo AT+QIACT? > /dev/ttyUSB3 sleep 0.3 echo AT+QFTPCFG=\"contextid\",$pdp > /dev/ttyUSB3 sleep 0.3 echo AT+QFTPCFG=\"account\",\"$ftp_user\",\"$ftp_password\" > /dev/ttyUSB3 sleep 3 echo AT+QFTPCFG=\"filetype\",1 > /dev/ttyUSB3 sleep 0.3 echo AT+QFTPCFG=\"transmode\",1 > /dev/ttyUSB3 sleep 0.3 echo AT+QFTPCFG=\"rsptimeout\",90 > /dev/ttyUSB3 sleep 0.3 #echo "connecting to FTP" echo AT+QFTPOPEN=\"$ftp_server\",21 > /dev/ttyUSB3 sleep 6.0 #echo "downloading extra2.bin file" echo -e at+qftpget=\"xtra2.bin\",\"RAM:xtra2.bin\" > /dev/ttyUSB3 sleep 5.0 #echo "closing ftp connection" echo at+qftpclose > /dev/ttyUSB3 sleep 0.3 #echo "enabling gps extra" echo at+qgpsxtra=1 > /dev/ttyUSB3 sleep 0.3 #echo "setting time as: $utctime" echo AT+QGPSXTRATIME=0,\"$utctime\",1,1,5 > /dev/ttyUSB3 sleep 0.3 #echo "checking if donwload is ok" echo AT+QFLST=\"RAM:*\" > /dev/ttyUSB3 sleep 0.3 #echo "updating gnss" echo AT+QGPSXTRADATA=\"RAM:xtra2.bin\" > /dev/ttyUSB3 sleep 5.0 #echo "deleting file" echo AT+QFDEL=\"RAM:xtra2.bin\" > /dev/ttyUSB3 fi # this mode does not work the QFUPL command does not work if [ $mode = "LOCAL" ] then echo at+qgpsxtra=1 > /dev/ttyUSB3 sleep 0.3 echo -e AT+QFUPL=\"RAM:xtra2.bin\",59763,90 > /dev/ttyUSB3 fi if [ $mode = "HTTP" ] then sleep 0.3 echo at+qhttpcfg=\"responseheader\",1 > /dev/ttyUSB3 sleep 0.3 echo at+qiact? > /dev/ttyUSB3 sleep 0.3 echo AT+QICSGP=1,1,\"m2minternet.apn\",\"\",\"\",3 > /dev/ttyUSB3 sleep 0.3 echo AT+QIACT=1 > /dev/ttyUSB3 sleep 0.3 echo AT+QIACT? > /dev/ttyUSB3 sleep 0.3 echo -e AT+QHTTPURL=40 > /dev/ttyUSB3 echo -e ' ' > /dev/ttyUSB3 sleep 1 echo AT+QHTTPGET=80 > /dev/ttyUSB3 sleep 5 echo -e AT+QHTTPREADFILE=\"RAM:xtra2.bin\",80 > /dev/ttyUSB3 sleep 6 echo "Finished downloading file" echo at+qgpsxtra=1 > /dev/ttyUSB3 sleep 0.3 echo "setting time" echo AT+QGPSXTRATIME=0,\"$utctime\",1,1,5 > /dev/ttyUSB3 sleep 0.3 echo "checking if donwload is ok" echo AT+QFLST=\"RAM:*\" > /dev/ttyUSB3 sleep 0.3 echo "updating gnss" echo AT+QGPSXTRADATA=\"RAM:xtra2.bin\" > /dev/ttyUSB3 sleep 0.3 echo "deleting file" echo AT+QFDEL=\"RAM:xtra2.bin\" > /dev/ttyUSB3 fi fi opt/wtc2.0/src/powerkey.sh0000755000175200017520000000047313557057144016125 0ustar bushnellbushnell#!/bin/sh echo 4c > /sys/devices/platform/axp81x_board/axp81x_reg REG=$(cat /sys/devices/platform/axp81x_board/axp81x_reg | sed -e 's/REG\[4c\]=//') #echo "REG=$REG" if [ $REG != 0 ] then echo 4cFF > /sys/devices/platform/axp81x_board/axp81x_reg #cat /sys/devices/platform/axp81x_board/axp81x_reg fi exit $REG opt/wtc2.0/src/sleep.rb0000644000175200017520000000165613557057144015362 0ustar bushnellbushnellrequire 'lte.rb' require 'quectel.rb' require 'syslog/logger' if __FILE__ == $0 r=-1 begin options = {} OptionParser.new do |opt| opt.on('-c', '--config config_file') { |o| options[:config_file] = o } end.parse! if options[:config_file] == nil puts("Missing -c=") exit(-2) end puts("Getting into sleep mode") m=LteModem.new(YAML.load(File.read(options[:config_file])).to_hashugar) q= QuectelATCommands.new(m.getCommandPort,m.getLogName) r = q.sendATCmdRaw("AT+CFUN=4") # shut down the Tx/Rx in order to remove option sleep(2) #system("rmmod option") # cannot be removed here, has to be another process #system("echo mem > /sys/power/state") rescue Exception => e puts("Exception: #{e}") puts(e.backtrace) exit(-5) end end opt/wtc2.0/src/mqtt_rpc.rb0000644000175200017520000001717613557057144016107 0ustar bushnellbushnellrequire 'mqtt' require 'securerandom' # uuid generator require 'json' # This module allows classes to become remote object over MQTT. By including # this module, you class' methods may be invoked remotely via an MQTT broker. # # This module also makes the MQTT topic (servicename) available for messages # other than RPC related. # # When the service is started, the classes methods are published to the MQTT broker as a retained message. # Upon exit, the message (retained) is delted. # # The list of methods allows the proxy object (clients) to discover the available methods. # # The messaging protocol is the following: # # The proxy object will send a message with the following topic: # # /api/call// # # - The message contents will be the method's parameters # - The uuid identifies the unique call to this method and allows the caller to identify the return message # # The server object will execute the method and send the following message as a return: # /api/response/ # The response message will contain the returned value of the method. # # Classes that include this module can implement a method named _handle_message() to receive messages that # are sent the specified topic, but are not meant to be related to the remote API. module MQTTServer # This is the connection to the MQTT broker. Classes that include this module can use it to send # not API messages to the broker. attr_reader :mqtt_broker_conn # Set to true to get additional sysloging. attr_accessor :debug # This method connects to the MQTT broker. connect_service and start_service are seperated # to allow the user to use the connection to do additional configurations such as subscribe # to additional topics, etc. Once the service is started, the calling thread will join # the serice thread and be blocked. start_service should be the last call. def connect_service(servicename, uri) @servicename = servicename @mqtt_broker_conn = MQTT::Client.connect(uri) end # This method will start the MQTT listening process. # Params: # # - service name: A unique name to identify this service. It must be unique accross the whole MQTT network. # - uri: The URI of the MQTT broker. def start_service() @debug = false @semaphore = Mutex.new begin # Publish our API for others to discover @mqtt_broker_conn.publish("#{@servicename}/api/methods", methods.to_json, retain = true) # Subscribe for API calls (anything really, we will discriminate between API calls # and other messages below. Any messages with the topic servciename, will be handled below # API calls are differenciated with other messages. API calls will be handle as such, other # messages will be forwarded so that a class that includes this module can handle it as it # sees fit. @mqtt_broker_conn.subscribe("#{@servicename}/#") # Begin receiving messages @mqtt_broker_conn.get(){|topic,message| # If this is a message related to the API/RPC protocol... if topic =~ %r{#{@servicename}/api/call} me, api, call, method_name, uuid = topic.split('/') begin # Determine if this class can handle this method if respond_to? method_name Log4Ienso.log.P_INFO("API message: #{msg.size}: => #{msg}") if debug msg = JSON.parse(message) @semaphore.synchronize{ ret = public_send(method_name, *msg) } end rescue Exception => e Log4Ienso.log.P_INFO("Exception while calling remote method: #{e}: #{e.backtrace}") ensure @mqtt_broker_conn.publish("#{@servicename}/api/response/#{uuid}",ret.to_json, retain = false) end elsif @semaphore.synchronize{ _handle_message(topic, message) if respond_to?(:_handle_message) } end } ensure # Make sure we remove the retained API reference from the MQTT broker @mqtt_broker_conn.publish("#{@servicename}/api/methods",nil , retain = true) end end # Can be used to determine if the remote object is there... def ping() :pong end end class MQTTObject attr_reader :_proxy_mqtt_broker def initialize(servicename, uri) @topic = "#{servicename}/api" @_proxy_mqtt_broker = MQTT::Client.connect(uri) @sericename = servicename # Send message to server asking for list of methods topic, methods = @_proxy_mqtt_broker.get(@topic + '/methods') @methods = JSON.parse(methods) end def method_missing(method, *args, &block) if @methods.include?(method.to_s) uuid = SecureRandom.uuid begin @_proxy_mqtt_broker.subscribe(@topic + "/response/" + uuid) @_proxy_mqtt_broker.publish(@topic + "/call/#{method}" + "/#{uuid}", args.to_json) topic, message = @_proxy_mqtt_broker.get ensure @_proxy_mqtt_broker.unsubscribe(@topic + '/response/' + uuid) message end else raise NoMethodError.new("undefined method `#{method}' for #{self}") end end end def send_synchronous(topic, args={}) uuid = SecureRandom.uuid mqtt_broker = MQTT::Client.connect(uri) begin mqtt_broker.subscribe(topic + "/response/" + uuid) mqtt_broker.publish(topic + "/call" + "/#{uuid}", args.to_json) topic, message = mqtt_broker.get ensure mqtt_broker.unsubscribe(topic + '/response/' + uuid) message end end if $0 == __FILE__ class Test1 include MQTTServer def initialize(num) @log = Logger.new(nil) @num = num @t = MQTTObject.new('test2','mqtt://localhost') end def bob() "hello bob: #{@num}" end def stan(args={}) #puts("creating object") puts(args) #puts("calling") #[1,2,3, {:hello => @num, :bye => 4}, 4, 5, "done", @t.bob()] end def stan puts('Empty stan') end def stan(str) puts(str) end end class Test2 include MQTTServer def initialize(num) @log = Logger.new(nil) @num = num end def bob() "hello bob test2: #{@num += 1}" end def stan [1,2,3, {:hello => @num, :bye => 4}, 4, 5, "done"] end def stan puts("empty stan") end end Thread.abort_on_exception = true puts("Creating thread") Thread.new{ o1 = Test1.new(1) puts("Starting service for test1") o1.start_service('test1','mqtt://localhost') } Thread.new{ o2 = Test2.new(2) o2.start_service('test2','mqtt://localhost') } sleep(2) server1 = MQTTObject.new('test1', 'mqtt://localhost') #server2 = MQTTObject.new('bob2', 'mqtt://localhost:8000') #puts server1.bob() #(1..20).each{|idx| # puts server2.stan() #} (1..2).each{|idx| puts server1.stan(:a => 1, :logger => nil) server1.stan server1.stan("hello world") } end opt/wtc2.0/src/work_que.rb0000644000175200017520000001304513557057144016101 0ustar bushnellbushnellrequire "thread" require "monitor" ## # A tunable work queue, designed to coordinate work between a producer and a pool of worker threads. # class WorkQueue VERSION = "2.5.4" ## # Creates an empty work queue with the desired parameters. # It's generally recommended to bound the resources used. # # ==== Parameter(s) # * +max_threads+ - Maximum number of worker threads. # * +max_tasks+ - Maximum number of queued tasks. # # ==== Example(s) # wq = WorkQueue.new 10, nil # wq = WorkQueue.new nil, 20 # wq = WorkQueue.new 10, 20 # def initialize(max_threads = nil, max_tasks = nil) self.max_threads = max_threads self.max_tasks = max_tasks @threads = [] @threads_waiting = 0 @threads.extend MonitorMixin @tasks = [] @tasks.extend MonitorMixin @task_enqueued = @tasks.new_cond @task_dequeued = @tasks.new_cond @task_completed = @tasks.new_cond @tasks_pending = 0 end ## # Returns the maximum number of worker threads. # This value is set upon initialization and cannot be changed afterwards. # # ==== Example(s) # wq = WorkQueue.new # wq.max_threads #=> Infinity # wq = WorkQueue.new 1, nil # wq.max_threads #=> 1 # def max_threads @max_threads end ## # Returns the current number of worker threads. # This value is just a snapshot, and may change immediately upon returning. # # ==== Example(s) # wq = WorkQueue.new 1 # wq.cur_threads #=> 0 # wq.enqueue_b { ... } # wq.cur_threads #=> 1 # def cur_threads @threads.size end ## # Returns the maximum number of queued tasks. # This value is set upon initialization and cannot be changed afterwards. # # ==== Example(s) # wq = WorkQueue.new # wq.max_tasks #=> Infinity # wq = WorkQueue.new nil, 1 # wq.max_tasks #=> 1 # def max_tasks @max_tasks end ## # Returns the current number of queued tasks. # This value is just a snapshot, and may change immediately upon returning. # # ==== Example(s) # wq = WorkQueue.new 1 # wq.enqueue_b { ... } # wq.cur_tasks #=> 0 # wq.enqueue_b { ... } # wq.cur_tasks #=> 1 # def cur_tasks ret = @tasks.size + (cur_threads() - @threads_waiting ) ret end ## # Schedules the given Block for future execution by a worker thread. # If there is no space left in the queue, waits until space becomes available. # # ==== Parameter(s) # * +params+ - Parameters passed to the given block. # # ==== Example(s) # wq = WorkQueue.new # wq.enqueue_b("Parameter") { |obj| ... } # def enqueue_b(*params, &block) enqueue block, params end ## # Schedules the given Proc for future execution by a worker thread. # If there is no space left in the queue, waits until space becomes available. # # ==== Parameter(s) # * +proc+ - Proc to be executed. # * +params+ - Parameters passed to the given proc. # # ==== Example(s) # wq = WorkQueue.new # wq.enqueue_p(Proc.new { |obj| ... }, "Parameter") # def enqueue_p(proc, *params) enqueue proc, params end ## # Waits until the tasks queue is empty and all worker threads have finished. # # ==== Example(s) # wq = WorkQueue.new # wq.enqueue_b { ... } # wq.join # def join @tasks.synchronize do @task_completed.wait_while { @tasks_pending > 0 } end end ## # Halt all worker threads immediately, aborting any ongoing tasks. # Resets all # # ==== Example(s) # wq = WorkQueue.new # wq.enqueue_b { ... } # wq.kill # def kill @tasks.synchronize do @threads.synchronize do @threads.each(&:exit) @threads.clear @threads_waiting = 0 end @tasks.clear @tasks_pending = 0 @task_dequeued.broadcast @task_completed.broadcast end end private ## # Sets the maximum number of worker threads. # def max_threads=(value) fail ArgumentError, "the maximum number of threads must be positive" if value && value <= 0 @max_threads = value || 1.0 / 0 end ## # Sets the maximum number of queued tasks. # def max_tasks=(value) fail ArgumentError, "the maximum number of tasks must be positive" if value && value <= 0 @max_tasks = value || 1.0 / 0 end ## # Schedules the given Proc for future execution by a worker thread. # def enqueue(proc, params) @tasks.synchronize do @task_dequeued.wait_until { @tasks.size < @max_tasks } @tasks << [proc, params] @tasks_pending += 1 @task_enqueued.broadcast end spawn_thread end ## # Enrolls a new worker thread. The request is only carried out if necessary. # def spawn_thread @tasks.synchronize do @threads.synchronize do if @threads.size < @max_threads && @threads_waiting <= 0 && @tasks.size > 0 @threads << Thread.new { run } end end end end ## # Repeatedly process the tasks queue. # def run loop do proc, params = dequeue begin proc.call(*params) rescue => e STDERR.puts e end conclude end ensure @threads.synchronize do @threads.delete Thread.current end end ## # Retrieves a task from the queue. # def dequeue @tasks.synchronize do @threads_waiting += 1 @task_enqueued.wait_while { @tasks.empty? } @threads_waiting -= 1 task = @tasks.shift @task_dequeued.broadcast return task end end ## # Wind up a task execution. # def conclude @tasks.synchronize do @tasks_pending -= 1 @task_completed.broadcast end end endopt/wtc2.0/src/version.rb0000644000175200017520000000020513557057144015724 0ustar bushnellbushnell class Version Version_code = "0.21.10" def initialize() end def get_version() Version_code end end opt/wtc2.0/src/lcd.rb0000644000175200017520000001647213557057144015016 0ustar bushnellbushnell require 'yaml' require 'optparse' require 'syslog/logger' require 'utils' require 'gpio' class LcdScreen # The Register Select (RS) PIN is used to indicate either an instruction or some # data to transfer RS_INSTRUCTION = 1 RS_DATA = 2 # List of data bus pins @bus = [] # Create an instance of the class. # params # - config: This parameter is meant to contain the application's config file content. See config.yaml for details. See also Control for how to instantiate this class. def initialize(config={}, mode = false) @lcd_state = true # Intialize the data bus @config = config @bus = [] @log = Syslog::Logger.new(@config.log_name) # Each data PIN is represented as an element in the array. # [d7, d6, d5, d4, d3, d2, d1, d0] @config.gpios_bus.each{|k,v| @bus << Gpio.new(v) @bus.last.direction='out' @bus.last.clear } # Initialize the LCD contorl pins # Register select (controls whether we are sending data or an instruction) @RS = Gpio.new(@config.gpios_ctrl.RS) @RS.direction='out' @RS.clear # Read/Write: Determines a read or write operation (data or # instruction, depending on RS) @RW = Gpio.new(@config.gpios_ctrl.RW) @RW.direction='out' @RW.clear # Enable pin. Used to effect transfer of data/instruction @EN = Gpio.new(@config.gpios_ctrl.EN) @EN.direction='out' @EN.clear # LCD intensity @PWM = Gpio.new(@config.gpios_ctrl.PWM) @PWM.direction='out' @PWM.clear # Power to the LCD device @POWER = Gpio.new(@config.gpios_ctrl.POWER) @POWER.direction='out' if (mode == false) @POWER.set else @POWER.clear end # Backlight to the LCD device @BLK = Gpio.new(@config.gpios_ctrl.BLK) @BLK.direction='out' if (mode == false) @BLK.set else @BLK.clear end # Backlight to the LCD device @KBD_BLK = Gpio.new(@config.gpios_ctrl.KBD_POWER) @KBD_BLK.direction='out' if (mode == false) @KBD_BLK.set else @KBD_BLK.clear end @mutex_send = Mutex.new @mutex_string = Mutex.new end def goto(row, col) if row == 1 set_cursor_position(col) elsif row == 2 set_cursor_position(col + 16) else raise("Invalid LCD row specification") end end def clear _send_instruction(0x01) end def turn_on_all_pixels goto(1,1) num = 16 while num > 0 _send_data(255) num = num -1 end goto(2,1) num = 16 while num > 0 _send_data(255) num = num -1 end end def display_on @lcd_state = true @RS.clear @RW.clear @EN.clear @PWM.clear @POWER.set @BLK.set @KBD_BLK.set init_lcd() end def display_off @POWER.clear @BLK.clear @KBD_BLK.clear @EN.clear @RS.clear @RW.clear @EN.clear @PWM.clear _write_8bits(0) @lcd_state = false end def busy? @RW.set puts(@bus[7].get) @RW.clear end # Send a whole string def write_string(string) #ß = 0xdf (°) string = string.gsub(/°/, 'ß') @mutex_string.synchronize{ string.each_char{|char| _send_data(char.ord) } } end def set_cursor(col) offset = 0 if(col >= 16) offset = 0x40 col = col % 16 end _send_instruction(0x80 | (col + offset)) end def set_cursor_onfoff(onoff) if onoff == true _send_instruction(0x0F) else _send_instruction(0x0C) end end private # This methods writes eight bits to the data bus. Each bit is written to eight # different lines/pins. def _write_8bits(value) @EN.set (0..7).each{|idx| @bus[idx].value(value & 0x01) value >>= 1 } sleep(0.002) #Data Setup time 80ns @EN.clear sleep(0.002) #Data Hold time 10ns end # This initialization sequence is specified in the datasheet # Here, we will configure for 8bits def init_lcd puts("init_lcd") _send_instruction(0x30) sleep(0.02) _send_instruction(0x30) sleep(0.02) _send_instruction(0x30) sleep(0.02) # Set function of LCD: # DL = 1, 8bit # N = 1; two line display # F = 0; 5x8 dot chars _send_instruction(0x3C) sleep(0.02) # Set display on, cursor on, blinking on # D = 1 # C = 1 # B = 1 _send_instruction(0x0E) sleep(0.02) # Entry mode: # #_send_instruction(0x06) #sleep(30) end # Send a value to the LCD, specifying what type of value it is; i.e. instuction # or data def _send(value, mode) @mutex_send.synchronize{ if mode == RS_INSTRUCTION @RS.clear elsif mode == RS_DATA @RS.set else raise("Invalid RS mode") end @RW.clear _write_8bits(value) }if @lcd_state == true end # Send an instruction def _send_instruction(value) _send(value, RS_INSTRUCTION) end # Send a single data value def _send_data(value) _send(value, RS_DATA) end def _set_addr(value) val = (value | 0x80) _send_instruction(val) end def set_cursor_position(position) if position >= 1 && position <= 16 _set_addr(position - 1) elsif position >= 17 && position <= 32 _set_addr(0x40 + (position - 17)) else raise("LCD character position invalid. Should be between 1 and 32 (2lines, 16 positions each)") end end def _read_8bits val = 0 @EN.set sleep(0.0001) (0..7).reverse_each{|idx| val <<= 1 v = @bus[idx].get val |= Integer(v) } @EN.clear sleep(0.0001) val end end # Test code... if $0 == __FILE__ Thread.abort_on_exception = true @config = YAML.load(File.open("wtc2_config_v0.0.2-a.yaml").read).to_hashugar sleep(2) lcd = LcdScreen.new(@config.lcdctrl) lcd.init_lcd() #lcd.display_on() #puts("Set display off") #lcd.display_off() lcd.clear() sleep(2) # puts("Set display on") lcd.display_on() # lcd.goto(1,1) lcd.write_string("1") # lcd.goto(1,16) lcd.write_string("2") # lcd.goto(2,1) lcd.write_string("3") # lcd.goto(2,16) lcd.write_string("4") # lcd.goto(1,7) lcd.write_string("wtc2.0") lcd.goto(2,7) lcd.write_string("World") # lcd.goto(4) # # loop{ # lcd.write_string('|') # sleep(0.2) # lcd.goto(4) # lcd.write_string('/') # sleep(0.2) # lcd.goto(4) # lcd.write_string('-') # sleep(0.2) # lcd.goto(4) # lcd.write_string('\\') # sleep(0.2) # lcd.goto(4) end opt/wtc2.0/src/testSlip.rb0000644000175200017520000000413413557057144016053 0ustar bushnellbushnell require 'json' require 'slip' require 'timeout' @fifo = File.new(ARGV[0], File::RDWR) @fifo.sync = true class CommPacket COMM_PACKET = [ # mesage type (two bytes) 0x00, 0x01, # CRC16 0x00, 0x00, # Packet format version 0x01 ] def initialize(data) COMM_PACKET << data # crc16 over the data crc = crc16(COMM_PACKET[5..-1]) end end def send_char(char) @fifo.write([char].pack('C')) end F=File.new("log_uart_comm.dat", File::RDWR | File::CREAT) F.sync = true def recv_char #printf("reading...") c = @fifo.readpartial(1).bytes[0] #puts(" done!") #F.write([c].pack('C')) c end p = { "a" => 1, "b" => "Hello" } #(1..5000).each{|idx| # p["a"] = idx # send_packet(p.to_json) # # puts("#{recv_packet.pack('c*')}") #} #loop{ # puts("#{recv_packet.pack('c*')}") #} #(1..100).each{|idx| # send_packet([0x01, 0x00, 0x00].pack("C*")) #puts("#{idx}) #{recv_packet.pack('c*').inspect}") #puts("#{idx})") # sleep(0.3) #} system(%Q(stty -F /dev/ttyS4 raw cs8 -ignpar -cstopb -echo -parenb -crtscts 115200)) #(1..100).each{|idx| loop{ @fifo.write([0xc0, 0x01, 0x00, 0x00, 0xc0].pack("C*")) begin status = Timeout::timeout(0.5){ cmd_id, reason, dummy = recv_packet puts("M0 woke us up because: #{("%08b" % reason)}") if (reason & 0x01) > 0 puts("PIR trigger") end if (reason & 0x02) > 0 puts("Transition to daytime") end if (reason & 0x04) > 0 puts("Transition to nightime") end #puts "#{idx}) " + @fifo.readpartial(1024).inspect # puts @fifo.readpartial(1024) # @fifo.write([0xc0, 0x01, 0x00, 0x00, 0xc0].pack("C*")) # puts @fifo.readpartial(1024).inspect true } break if status rescue Timeout::Error => e puts("Timedout waiting. Retrying...") end } #sleep(0.1) #} opt/wtc2.0/src/lensfocusutility.rb0000644000175200017520000002453613557057144017701 0ustar bushnellbushnell#!/usr/bin/ruby # The following is an instruction to rdoc. It specifies the main page for the documentation. # This directive must appear in a .rb file. We placed it here because this is the main # control of the application. # :main: README.txt $LOAD_PATH.push File.expand_path("..", __FILE__) $video_recording = false $imei= nil $iccid= nil require 'yaml' require 'json' require 'optparse' require 'syslog/logger' require 'utils' require 'menu' require 'view' require 'timer' require 'comm' require 'env' require 'work_que' #require 'nmea' require 'camera' require 'keypad' require 'picture_manager' require "monitor" require "connection_manager" require 'version' require 'gpio' require 'mqtt' require 'debug' Thread.abort_on_exception = true # Developer note # # To make the image for the lensfoucs software # # 1) in start.sh make the lensfocus same as control.rb # 2) change in enablehotspot.sh # 3) Use the make_imagev2.sh script to make the image - using latest kernel - make bpi and make in application class Test include EventListener #possible states of the modem MODEM_REBOOT = 0 # modem will not work wihout a reboot of quectel modem, should sleep MODEM_OFF = 1 # covers suspended and low power mode sleep and fails, can sleep MODEM_CONNECTING = 2 # in the process of switching on and dialing ppp, cannot sleep MODEM_PORTS_AVAILABLE = 3 # can talk to A83, but no network as yet MODEM_CONNECTED = 4 # got ip and wating for job, cannot sleep MODEM_STARTING_UPLOAD = 5 # starting upload or in the midst of it, cannot sleep MODEM_FINISHED_UPLOAD = 6 # complted upload , cannot sleep until no more uploads / downloads MODEM_IDLE = 7 # all work done can go to sleep:103 # params: # - config: This is the contents of the application configuration file. See config.yaml for details. def initialize(config={}) @config = config @keypad = nil @log = Syslog::Logger.new(@config.control.log_name) @set_field_scan_flag=true @take_picture_in_process=false @remaining_pictures_no=0 # Network Variables @modem=nil @quectelcmds=nil @thread_photo = nil @thread_modem = nil @thread_gps = nil @imei=@iccid="0" @rssi = 0 @networkstate=0 #0 not available, 1 available @modemstate=0 #0 not enabled, 1 enabled @wakeupcounter=0 @modem_state = MODEM_OFF @version = Version.new() @sleep_count = 0 @isMenuDirty = false @wakeupcounter = 0 #count the number of wakeups in this session @read_bat_counter = 0 @image_to_network_try = 0 @latitude = @longitude = @satellite = @gps_errcode =0 @location_available = false # Developer note: setting this to true will stop execution of GPS code @dailycheckin = true # TO DO set to false once daily timer is enabled @storageused = @storagesize = 0 @connmanager = nil @wifi="default" @btnmode = 0 @BLK=nil @ledstatus = true @streamingstarted = 0 # Load Environment setting file and International Language descript @env = Env.new(config.def_env) @turn_on_display_flag = false Log4Ienso.log.P_NOTICE("starting modem") @status = 1 @BLK = Gpio.new("PD25") @BLK.direction='out' @th = Thread.new{ startLedIndicator } Log4Ienso.log.P_NOTICE("Starting LensFocus software #############") startLensFocus end def startLensFocus count = 0 while @status != 0 @status = startModemandNetwork(@env.get_env_value('Select_Network'),0) Log4Ienso.log.P_NOTICE("Status is #{@status}") if @status == 5 @ledstatus = false Log4Ienso.log.P_NOTICE("Status is #{@status} ############# Resetting #############") sleep 0.2 system("/opt/wtc2.0/src/sleep.sh") end count+=1 if count > 3 break end end mode = 0 Log4Ienso.log.P_NOTICE("checking mode .................") filesig = `cat /media/sd-mmcblk0p1/lensfocus.txt | head -1` Log4Ienso.log.P_NOTICE("File is #{filesig}") if filesig.downcase.chop.strip != "lensfocus" mode = 0 Log4Ienso.log.P_NOTICE("Default mode") else @wifi = `cat /media/sd-mmcblk0p1/lensfocus.txt | head -2 | tail -1` @wifi = @wifi.chomp.strip mode = 1 Log4Ienso.log.P_NOTICE("Lensfocus mode with wifi [#{@wifi}]") end # Instantiate all objects #@view = Display.new(@config.lcdctrl, desc) @camera = CameraControl.new(@config.camctrl, @env) @comm = Comm.new(@config.m0ctrl, [[0x02,@env.get_env_value('Set_photocell')],[0x06,@env.get_env_value('imaage_interval')], [0x0c,@env.get_env_value('capture_mode'), @env.get_env_value('movie_length')] ]) @version_m0 = @comm.get_mo_revision() Log4Ienso.log.P_NOTICE("==== @version_m0=#{@version_m0 } =====") @camera.add_listener(self) @comm.add_listener(self) @comm.interrupt_mask(false) #camera_get_set_day_night() @comm.interrupt_mask(false) #@picman.start() #initial_M0() @camera.set_day sleep(1) `killall hostapd | sh` sleep(4) `modprobe -v 8723bs` sleep(1) if mode == 1 Log4Ienso.log.P_NOTICE("In custom mode [#{@wifi}]") x = "sed -i s/SSIDNAME=.*/SSIDNAME=#{@wifi}/g /opt/wtc2.0/src/enablehotspot.sh" system("#{x}") sleep 2 end system("/opt/wtc2.0/src/enablehotspot.sh") sleep(1) @camera.start_streaming(1) #lens focus mode , set to 0 for full screen streaming @streamingstarted = 1 # Listent to keypad events @keypad = Keypad.new(@config.keypadctrl) @keypad.add_listener(self) #system("/opt/wtc2.0/src/streamf.sh") end def sleep_control( param = nil) sleep (0.1) end def startLedIndicator state=false counter = 0 while state == false if ($imei == nil && @ledstatus==true) || @streamingstarted == 0 || counter < 20 @BLK.clear sleep 1.0 @BLK.set sleep 1.0 if @streamingstarted == 1 counter+=1 next end end if @ledstatus == false @BLK.clear break end if $imei != nil && @streamingstarted == 1 @BLK.set break end end end def startModemandNetwork(networkname,starttype) status = 5 Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} Starting Modem Loop --") @ledstatus = true if @connmanager == nil Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} starting conn 2") @connmanager = ConnectionManager.new(@config) end status = @connmanager.startModemForLensFocusTest() return status end # This methods handles events that were generated by EventSource that we registered to. # See new for a list of sources to which we register. def handle_event(event, data = nil) # Camera has finished capturing an image. if event =~ %r{keypad/keypress} @keypressed = data[:name] count = 0 while @btnmode != 0 sleep 0.1 end puts("the key pressed is " + @keypressed.to_s) if @keypressed != nil if @keypressed.strip.chomp == "Left" @camera.set_night Log4Ienso.log.P_NOTICE("setting to night") @btnmode = 1 sleep 0.2 while count < 3 picfile=$imei+"_N"+"_"+count.to_s+".jpg" cmd ="wget http://localhost:8080/?action=snapshot -O /media/sd-mmcblk0p1/"+picfile Log4Ienso.log.P_NOTICE("File: #{cmd}") system(cmd) sleep 0.2 `sync` count+=1 end @btnmode = 0 end if @keypressed.strip.chomp == "Right" @camera.set_day Log4Ienso.log.P_NOTICE("setting to day") @btnmode = 1 sleep 0.2 count = 0 while count < 3 picfile=$imei+"_D"+"_"+count.to_s+".jpg" cmd ="wget http://localhost:8080/?action=snapshot -O /media/sd-mmcblk0p1/"+picfile Log4Ienso.log.P_NOTICE("File: #{cmd}") system(cmd) sleep 0.2 `sync` count+=1 end @btnmode = 0 end end end end end options = { } optparse = OptionParser.new{|opt| opt.banner = 'This is the service template' opt.on('-cPATH', '--config=PATH', 'Location of the config file.'){|arg| raise("File #{arg} does not exit.") if not File.exists?(arg) options[:config_path] = arg } } optparse.parse! begin options.assert_keys(:config_path) rescue puts("--config=path must be specified") exit(-1) end begin con = Test.new(YAML.load(File.read(options[:config_path])).to_hashugar) loop do puts("..") sleep(1) end puts "Test Done" rescue Exception => e puts("Exception: #{e}") puts(e.backtrace) log = Syslog::Logger.new("wtc2.0") log.fatal("Exception: #{e}") log.fatal(e.backtrace) end opt/wtc2.0/src/env/0000755000175200017520000000000013557057144014505 5ustar bushnellbushnellopt/wtc2.0/src/env/desc_en.yml0000644000175200017520000000564113557057144016636 0ustar bushnellbushnellstatus: 'STATUS' config: 'CONFIG' 1_second: '1 SEC' 2_second: '2 SEC' 3_second: '3 SEC' 4_second: '4 SEC' 5_second: '5 SEC' 6_second: '6 SEC' 7_second: '7 SEC' 8_second: '8 SEC' 9_second: '9 SEC' 10_second: '10 SEC' 15_second: '15 SEC' 20_second: '20 SEC' 25_second: '25 SEC' 30_second: '30 SEC' 35_second: '35 SEC' 40_second: '40 SEC' 45_second: '45 SEC' 50_second: '50 SEC' 55_second: '55 SEC' 60_second: '60 SEC' 1_minute: '1 MIN' 2_minute: '2 MIN' 3_minute: '3 MIN' 4_minute: '4 MIN' 5_minute: '5 MIN' 6_minute: '6 MIN' 7_minute: '7 MIN' 8_minute: '8 MIN' 9_minute: '9 MIN' 10_minute: '10 MIN' 15_minute: '15 MIN' 20_minute: '20 MIN' 25_minute: '25 MIN' 30_minute: '30 MIN' 35_minute: '35 MIN' 40_minute: '40 MIN' 45_minute: '45 MIN' 50_minute: '50 MIN' 55_minute: '55 MIN' 60_minute: '60 MIN' dummy1: 'DUMMY 1' dummy2: 'DUMMY 2' dummy3: 'DUMMY 3' dummy4: 'DUMMY 4' lcd_off_time: 'LCD OFF TIME' upload_thumb: 'UPLOAD THUMB' 1_copy: '1' 2_copy: '2' 3_copy: '3' 4_copy: '4' 5_copy: '5' normal: 'Normal' high: 'HIGH' med: 'MED' auto: 'AUTO' low: 'LOW' day: 'DAY' night: 'NIGHT' set: 'SET' 'off': 'OFF' 'on': 'ON' 'yes': 'YES' 'no': 'NO' saved: 'SAVED' every_shot: 'NOW' once_per_day: 'DAILY' n/a: 'N/A' daily: 'DLY' version check: 'VERSION CHECK' upgrade_firmware: 'UPGRADE FIRMWARE' Upgrade A83: 'UPGRADE A83' Upgrade M0: 'UPGRADE M0' now: 'NOW' never: 'NVR' mode: 'MODE' photo: 'PHOTO' video: 'VIDEO' setup: 'SETUP' network: 'NETWORK' file_logging: 'LOGGING' setime: 'SET TIME' time_ofoperation: 'TIME OF OP' days: 'DAYS' mon_fri: 'M-F' sat: 'Sat' sun: 'Sun' blk0: 'BLOCK1' blk1: 'BLOCK2' blk2: 'BLOCK3' blk3: 'BLOCK4' tracking: 'TRACKING' cam: 'Cam' report_interval: 'SEND IMAGE' embedded_gps: 'EMBED GPS' pir: 'PIR' overwrite: 'OVERWRITE' camera_name: 'CAMERA NAME' format_s/d: 'ERASE S/D' diagnostics: 'DIAGNOSTICS' image_resoluition: 'IMAGE MP' capture_count: 'NUM PICS' imaage_interval: 'DELAY' led_power: 'LED' shutter_speed: 'SHUTTER' show_timestamp: 'TIMESTAMP' pic_format: 'PIC FORMAT' trigger_time: 'Trigger Time' field_scan: 'FIELD SCAN' scan_ab: SCAN a_char: 'A' b_char: 'B' m_char: 'M' interval: 'DLY' 1_minute2: '01M' 5_minute2: '05M' 10_minute2: '10M' 15_minute2: '15M' 30_minute2: '30M' 60_minute2: '60M' 3to2: '3:2' 16to9: '16:9' capture_mode: 'IMG. TYPE' movie_resoluition: 'VID' movie_length: 'VID LENGTH' movie_interval: 'DELAY' movie_led_power: 'LED' hybrid: 'HYBRID' 720p30: '720P' 1080p30: '1080P' 640x480: '640x480' 960x540: '960x540' network_settings: 'NETWORK SETTING' send_test_image: 'SEND TEST IMAGE' camera_mode: 'Camera Mode' set_clock: 'Set Clock' gps_co-ordinates: 'GPS co-ordinates' video_sound : 'Video Sound' wirless_on/off: 'WIRELESS' sd_card_full: 'SD CARD FULL' no_sd_card: 'NO SD CARD' still: 'Still' rdy: 'RDY' cap: 'CAP' image: 'PHOTO' loading: 'LOADING...' reading_sd: 'Reading SD ...' recording: 'Recording Video' wait: 'Please wait...' timer: 'TIMER' pir_mode: 'PIR MODE' sig: 'SIG' restore_default: 'RESTORE DEFAULT' opt/wtc2.0/src/streamf.sh0000755000175200017520000000121613557057144015715 0ustar bushnellbushnell#!/bin/sh # make sure the ramdisk is ther # mount -t ramfs -o size=5m ramfs /root/ram1 #v42grab -q 50 --mmap -W 320 -H 240 -c -I 10 -o /root/ram1/cam.jpg & #/usr/bin/mjpg_streamer -i "input_file.so -f /root/ram1 cam.jpg -d 0" -o "output_http.so -w /usr/www" mkdir -p /streaming mount -t ramfs -o size=5m ramfs /streaming sleep 2 echo "Starting streaming" #id=`ps -ef | awk '/[b]ushnell-cam-capture/{print $1}'` #kill -9 $id #sleep 2 #v4l2grab -W 960 -H 540 -c -o /streaming/cam.jpg & #bushnell-streaming 1280 720 /streaming/cam &> /dev/null & /usr/bin/mjpg_streamer -i "input_file.so -f /streaming cam.jpg -d 0" -o "output_http.so -" opt/wtc2.0/src/disablewebserver.sh0000755000175200017520000000013113557057144017577 0ustar bushnellbushnell#remove web server #!/bin/sh id="$(ps -ef | awk '/[w]ebserver/{print $1}')" kill -9 $idopt/wtc2.0/src/ppp_scripts/0000755000175200017520000000000013557057144016263 5ustar bushnellbushnellopt/wtc2.0/src/ppp_scripts/quectel-ppp0000644000175200017520000000035513557057144020450 0ustar bushnellbushnell/dev/config_var_port 115200 user "" password "" connect 'chat -s -v -f /etc/ppp/peers/quectel-chat-connect' disconnect 'chat -s -v -f /etc/ppp/peers/quectel-chat-disconnect' hide-password noauth debug defaultroute noipdefault nobsdcomp opt/wtc2.0/src/ppp_scripts/quectel-chat-disconnect0000644000175200017520000000017513557057144022717 0ustar bushnellbushnellABORT "ERROR" ABORT "NO DIALTONE" SAY "\nSending break to the modem\n" "" +++ "" +++ "" +++ SAY "\nGoodbay\n" opt/wtc2.0/src/ppp_scripts/quectel-chat-connect0000644000175200017520000000036013557057144022213 0ustar bushnellbushnellABORT "BUSY" ABORT "NO CARRIER" ABORT "NO DIALTONE" ABORT "ERROR" ABORT "NO ANSWER" TIMEOUT 30 "" AT OK ATE1 OK ATI;+CSUB;+CSQ;+CPIN?;+COPS?;+CGREG?;+CEREG?;&D2 OK AT+CGDCONT=1,"IP","config_var_apn",,0,0 OK config_var_dialcode CONNECT '' opt/wtc2.0/src/shutradios.sh0000755000175200017520000000016313557057144016441 0ustar bushnellbushnell#shutdown bt, lte and wifi #cd /sys/devices/platform/axp81x_board/ #echo 12 >axp81x_reg #echo 1200 > axp81x_reg opt/wtc2.0/src/wtc2_config_v0.0.2-a.yaml0000644000175200017520000003657613557057144020147 0ustar bushnellbushnell global: logger: Logger(STDOUT) storage_location: /media/photos/DCIM/ remote: url: https:// camera: default_resolution: height: 3264 width: 2160 mqtt: log_name: wtc2-mqtt control: topic: control uri: mqtt://localhost ledctrl: topic: ledctrl uri: mqtt://localhost camctrl: topic: camctrl uri: mqtt://localhost keypadctrl: topic: keypadctrl uri: mqtt://localhost lcdctrl: topic: lcdctrl uri: mqtt://localhost ftp: servername: ftp.wirelesstrophycam.com username: ftpuser password: ftpuser control: log_name: wtc2-control ledctrl: log: wtc2-ledctrl gpios: - PD29 ltectrl: log_name: wtc2-ltemodem gpio: power: number: PE19 direction: out value: 0 modem: number: PE12 direction: out value: 0 vbus: number: PD20 direction: out value: 0 status: number: PD27 direction: in value: 1 tty_port_count: 5 tty_data: /dev/ttyUSB2 tty_command: /dev/ttyUSB3 tty_ghostport: /dev/ttyUSB5 tty_list: /dev/ttyU* network: rogers_can: apn: ltemobile.apn username: password: pdp: 1 iptype: IP dialcode: ATD*99# verizon: apn: vzwinternet username: password: pdp: 3 iptype: IPV4V6 dialcode: ATD*99***3# atandt: apn: bnwtc.zipitwireless.com.attz username: password: pdp: 1 iptype: IP dialcode: ATD*99# rogers_us: apn: m2minternet.apn username: password: pdp: 1 iptype: IP dialcode: ATD*99# kpn: apn: internet.m2m username: password: pdp: 1 iptype: IP dialcode: ATD*99# bellca: apn: mnet.bell.ca.ioe username: password: pdp: iptype: dialcode: timeserver: time.nist.gov cloud_service_provider: zipit: end_point: https://server.wirelesstrophycam.com:8001 lte_config: config_folder: /var/wtc2.0 config_file: lte.config token_file: session.id lcdctrl: log_name: wtc2-lcdctrl gpios_ctrl: EN: PD12 RW: PD13 RS: PD14 PWM: PD28 POWER: PD29 BLK: PC7 KBD_POWER: PD25 gpios_bus: d0: PD2 d1: PD3 d2: PD4 d3: PD5 d4: PD6 d5: PD7 d6: PD10 d7: PD11 m0ctrl: log_name: m0ctrl tty: /dev/ttyS4 gpio_int: :gpio: PH9 :name: M0 interrupt :edge: 'rising' gpio_reset: PE8 gpio_boot0: PE9 actions: no_sd_card: proc{puts("hello")} keypadctrl: log_name: wtc-keypadctrl buttons: - :gpio: PL3 :name: Up :edge: falling - :gpio: PL7 :name: Down :edge: falling - :gpio: PL5 :name: Left :edge: falling - :gpio: PL6 :name: Right :edge: both - :gpio: PL4 :name: Enter :edge: both - :gpio: PL2 :name: Menu :edge: both camctrl: log_name: wtc2-camctrl default_resolution: height: 1080 width: 1920 ir_leds: gpios: enable_positive: PD15 enable_negagive: PD26 high_current_enable: PD18 ir_filter: gpios: power: PD21 direction_positive: PD23 direction_negative: PD22 present_signal_value: 0 # GPIO signal (high/low) value to indicate the IR cut filter is in front of the lens missing_signal_value: 1 # GPIO signal (high/low) value to indicate the IR cut filter is _not_ in front of the lens default_setting: present # daytime operation pulse_width: 0.200 # 100ms voltage pulse to move the filter. cap_application: path: /opt/wtc2.0/capture/ txfifo: /tmp/bushnell-trailcam-fifo-to-c rxfifo: /tmp/bushnell-trailcam-fifo-to-ruby pid_file: /var/run/wtc2-capture.pid gps: tty: /dev/ttyS1 gpios: green_led: red_led: blue_led: button_up: picman: log_name: wtc2-picman pic_path: /media/photos/DCIM/ thumb_path: /media/photos/thumb/ input_path: /tmp/ max_error_count: 50 min_free_disk: 10240 messages: no_sd_card: SD card is missing. Picture not saved. mqtt_connection: default: Failed to connect to MQTT broker def_env: fake_pir_cntr: selected: '0' fake_pmic_pir_cntr: selected: '0' nfake_pir_cntr: selected: '0' reset_cntr: selected: '0' reset_time: selected: '0' path: 'env/' name: 'env.yml' desc_file: selected: 'desc_en.yml' candidate: - 'desc_en.yml' - 'desc_kr.yml' - 'desc_fr.yml' lcd_off_time: selected: '20_second' candidate: - '10_second' - '20_second' - '40_second' - 'never' time_ofoperation: enable: selected: 'off' candidate: - 'off' - 'on' days: selected: 'mon_fri' candidate: - 'mon_fri' - 'sat' - 'sun' off_on: selected: - '0/0/0/0' - '0/0/0/0' - '0/0/0/0' time: selected: - '00:00/06:00/12:00/18:00' - '00:00/06:00/12:00/18:00' - '00:00/06:00/12:00/18:00' Set_photocell: selected: '100' candidate: - '100' - '150' - '200' - '250' - '300' - '350' - '400' - '450' - '500' Select_Network: selected: 'ROGERS-US' candidate: - 'ATT' - 'KPN' - 'VERIZON' - 'ROGERS-US' - 'ROGERS-CAN' lcd_force_on: selected: 'off' candidate: - 'on' - 'off' camera_name: selected: CAMERA1 wirless_on/off: selected: 'on' candidate: - 'on' - 'off' report_interval: selected: 'now' candidate: - 'now' - 'daily' - 'never' overwrite: selected: 'on' candidate: - 'on' - 'off' capture_mode: selected: 'image' candidate: - 'image' - 'video' #- 'hybrid' hybrid: selected: 'off' candidate: - 'off' - 'on' capture_count: selected: '1_copy' candidate: - '1_copy' - '2_copy' - '3_copy' - '4_copy' - '5_copy' shutter_speed: selected: 'med' candidate: - 'low' - 'med' - 'high' trigger_time: selected: '50' candidate: - '50' - '70' - '90' - '100' image_resoluition: selected: '8' candidate: - '2' - '5' - '8' - '20' movie_resoluition: selected: '720p30' candidate: - '720p30' - '1080p30' - '640x480' #- '960x540' movie_length: selected: '10_second' candidate: #- '1_second' #- '2_second' #- '3_second' #- '4_second' - '5_second' - '6_second' - '7_second' - '8_second' - '9_second' - '10_second' - '15_second' - '20_second' - '25_second' - '30_second' - '35_second' - '40_second' - '45_second' - '50_second' - '55_second' - '60_second' movie_interval: selected: '10_second' candidate: - '1_second' - '2_second' - '3_second' - '4_second' - '5_second' - '6_second' - '7_second' - '8_second' - '9_second' - '10_second' - '15_second' - '20_second' - '25_second' - '30_second' - '35_second' - '40_second' - '45_second' - '50_second' - '55_second' - '60_second' imaage_interval: selected: '1_minute' candidate: - '1_second' - '2_second' - '3_second' - '4_second' - '5_second' - '6_second' - '7_second' - '8_second' - '9_second' - '10_second' - '15_second' - '20_second' - '25_second' - '30_second' - '35_second' - '40_second' - '45_second' - '50_second' - '55_second' #- '60_second' - '1_minute' - '2_minute' - '3_minute' - '4_minute' - '5_minute' - '6_minute' - '7_minute' - '8_minute' - '9_minute' - '10_minute' - '15_minute' - '20_minute' - '25_minute' - '30_minute' - '35_minute' - '40_minute' - '45_minute' - '50_minute' - '55_minute' - '60_minute' led_power: selected: 'med' candidate: - 'low' - 'med' - 'high' pic_format: selected: '3to2' candidate: - '3to2' - '16to9' show_timestamp: selected: 'on' candidate: - 'on' - 'off' field_scan: selected: 'off' candidate: - 'off' - 'on' scan_ab: selected: 'a_char' candidate: - 'a_char' - 'b_char' interval_a: selected: '5_minute2' candidate: - '1_minute2' - '5_minute2' - '10_minute2' - '15_minute2' - '30_minute2' - '60_minute2' interval_b: selected: '5_minute2' candidate: - '1_minute2' - '5_minute2' - '10_minute2' - '15_minute2' - '30_minute2' - '60_minute2' start_time_a: selected: '05:00' end_time_a: selected: '09:00' start_time_b: selected: '15:00' end_time_b: selected: '20:00' embedded_gps: selected: 'on' candidate: - 'on' - 'off' latitude: selected: "N 43°51'15.2\"" longitude: selected: "W 079°23'01.5\"" diagnostics: selected: 'off' candidate: - 'on' - 'off' gps_tracking: selected: 'off' candidate: - 'on' - 'off' switch_on/off_gps: selected: 'off' candidate: - 'on' - 'off' pir_mode: selected: 'on' candidate: - 'on' - 'day' - 'night' - 'timer' - 'off' pir: selected: 'auto' candidate: - 'auto' - 'high' - 'med' - 'low' file_logging: selected: 'off' candidate: - 'on' - 'off' tracking: selected: 'off' candidate: - 'on' - 'off' dailycheckin: selected: 0 candidate: - 0 - 1 - 2 activecommstate: #to manage server connection across reboots selected: 0 candidate: - 0 # now - 1 # daily mode - 2 # never dstrebootcheck: selected: 0 candidate: - 0 #not applied - 1 #applied provider: '310': country: "us" mnc_digits: 3 providers: '038': name: 'AT&T' apn: 'bnwtc.zipitwireless.com.attz' '090': name: 'AT&T' apn: 'bnwtc.zipitwireless.com.attz' '150': name: 'AT&T' apn: 'bnwtc.zipitwireless.com.attz' '170': name: 'AT&T' apn: 'bnwtc.zipitwireless.com.attz' '410': name: 'AT&T' apn: 'bnwtc.zipitwireless.com.attz' '560': name: 'AT&T' apn: 'bnwtc.zipitwireless.com.attz' '680': name: 'AT&T' apn: 'bnwtc.zipitwireless.com.attz' '004': name: 'VERIZON' apn: 'vzwinternet' '012': name: "VERIZON" apn: "vzwinternet" '311': country: "us" mnc_digits: 3 providers: '038': name: 'AT&T' apn: 'bnwtc.zipitwireless.com.attz' '090': name: 'AT&T' apn: 'bnwtc.zipitwireless.com.attz' '150': name: 'AT&T' apn: 'bnwtc.zipitwireless.com.attz' '170': name: 'AT&T' apn: 'bnwtc.zipitwireless.com.attz' '410': name: 'AT&T' apn: 'bnwtc.zipitwireless.com.attz' '560': name: 'AT&T' apn: 'bnwtc.zipitwireless.com.attz' '680': name: 'AT&T' apn: 'bnwtc.zipitwireless.com.attz' '480': name: 'VERIZON' apn: 'vzwinternet' '012': name: "VERIZON" apn: "vzwinternet" '302': country: "canada" mnc_digits: 3 providers: '720': name: "ROGERS_CANADA" apn: "m2minternet.apn" '220': name: "telus" apn: "telus_apn" '204': country: "holand" mnc_digits: 2 providers: '08': name: "KPN" apn: "internet.m2m" '10': name: "KPN" apn: "internet.m2m" opt/wtc2.0/src/lte.rb0000644000175200017520000005345613557057144015043 0ustar bushnellbushnellrequire 'timeout' require 'yaml' require 'optparse' require 'syslog/logger' require 'mqtt_rpc' require 'utils' require 'gpio' require 'dem' require 'debug' require 'constants' # Lte modem setup and ppp connection management # class LteModem include EventSource include EventListener # Create an instance of the class. # params # - args: This parameter is meant to contain the application's config file content. See config.yaml for details. See also Control for how to instantiate this class. def initialize(args={}) # Intialize the data bus @args = args @log = Syslog::Logger.new(@args.control.log_name) @connected = 0 @network_ip= nil @power = nil @modem = nil @vbus = nil if File.exist?("/etc/ppp/connect-errors") system("echo '' > /etc/ppp/connect-errors") #clear the ppp errors log Log4Ienso.log.P_INFO("[LTE] cleared ppp log") end @cfolder = @args.ltectrl.lte_config.config_folder @cfile = @cfolder+"/"+@args.ltectrl.lte_config.config_file if !File.exist?(@cfile) Log4Ienso.log.P_CLEAN("[LTE] Making folder for config file : #{@cfile} ") `mkdir -p #{@cfolder}` `touch #{@cfile}` end end #call this function to start the modem on a boot /resume #the option driver must be loaded def shutdownModem() Log4Ienso.log.P_INFO("Shutting down modem") @modem = Gpio.new(@args.ltectrl.gpio.modem.number) @modem.direction = @args.ltectrl.gpio.modem.direction count=0 Log4Ienso.log.P_INFO("Setting power key to high") @status = Gpio.new(@args.ltectrl.gpio.status.number) #if status pin is high i.e modem disconnected pinstatus = @status.get Log4Ienso.log.P_INFO("Pulsing powerkey (PE12) to high - starting pulse...") @modem.set sleep(1) @modem.clear Log4Ienso.log.P_INFO("Waiting for 30 seconds...") sleep(35) pinstatus = @status.get if pinstatus.to_i == 1 Log4Ienso.log.P_INFO("Modem is now powered down with statuspin #{pinstatus}...") else Log4Ienso.log.P_INFO("Failed to powerdown modem - statuspin #{pinstatus}...") end end def enableModemBG96(starttype) @vbus = Gpio.new(@args.ltectrl.gpio.vbus.number) @vbus.direction = @args.ltectrl.gpio.vbus.direction @vbus.set Log4Ienso.log.P_CLEAN("#{Time.now.strftime("%H:%M:%S.%L")} Modem USB Connected - can talk to A83 now") notify("lte/started") return end def enableModem(starttype) i=0 powerkey = 0 #`rm -rf /dev/ttyUSB*` #clear the usb ports if any # check that the driver has loaded, usually happens on resume if starttype != Constant::COLD_BOOT driverchk='' driverchk=`lsmod | cut -d" " -f0 | grep option` if driverchk.chomp != 'option' system("modprobe -v option") sleep(0.2) end end #if starttype == Constant::COLD_BOOT #fix for high sleep current on boot # Log4Ienso.log.P_INFO("MODEM is in cold boot, will try ") # system(%Q(/opt/wtc2.0/src/pulse.sh)) # return 5 #end Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} STARTING MODEM") @modem = Gpio.new(@args.ltectrl.gpio.modem.number) @modem.direction = @args.ltectrl.gpio.modem.direction @vbus = Gpio.new(@args.ltectrl.gpio.vbus.number) @vbus.direction = @args.ltectrl.gpio.vbus.direction Log4Ienso.log.P_INFO("Check PD27 status pin") @status = Gpio.new(@args.ltectrl.gpio.status.number) #if status pin is high i.e modem disconnected @status.direction = @args.ltectrl.gpio.status.direction sleep (0.2) pinstatus = @status.get Log4Ienso.log.P_INFO("Status pin is " + pinstatus.to_s) # try 3 times and pulse for 3.5 seconds each time while i < 3 and pinstatus.chomp.strip =="1" do Log4Ienso.log.P_INFO("Set powerkey (PE12) to high - starting pulse") @modem.set powerkey = 1 Log4Ienso.log.P_INFO("Status pin is high, trying for 3.5 seconds ......") count = 0 # each count is 100 ms while count < 35 do #check for 3.5 seconds if pinstatus.chomp.strip == "0" #if status pin low, end pulse and set vbus to low Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} Status pin is low - ending pulse") @modem.clear Log4Ienso.log.P_INFO("Setting power key (PE12) to low") break end sleep(0.1) count += 1 pinstatus = @status.get end i+=1 end @modem.clear if pinstatus.chomp.strip == "0" Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} >>>>>>>>>> Status pin is low, can connect to modem <<<<<<<<<<") if powerkey == 1 Log4Ienso.log.P_INFO("Giving 13 seconds delay for VBUS (PD20) ") sleep(13) Log4Ienso.log.P_INFO("Setting VBUS (PD20) to high") powerkey = 0 end @vbus.set Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} VBUS (PD20) is now high") driverchk='' if starttype == Constant::COLD_BOOT Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} Loading / Reloading USB driver on cold boot") system("modprobe -v option") sleep(2) Log4Ienso.log.P_INFO("USB driver loaded") end else Log4Ienso.log.P_ERR("#{Time.now.strftime("%H:%M:%S.%L")} <<<<<<<<<< Status pin is high, cannot connect to modem >>>>>>>>>>>>") return 5 end if starttype == Constant::COLD_BOOT Log4Ienso.log.P_INFO("On coldboot need to wait for modem to come up...sleeping") sleep(15) #(30) Log4Ienso.log.P_INFO("Modem is now powered up...") end # a ghostDataPort /dev/ttyUSB5 in lieu of the /dev/ttyUSB2 # occurs when sometimes during the sleep-resume # process the option driver unloading fails due to reset of usb-hub if File.exist?(@args.ltectrl.tty_ghostport) # kill the pppd process and then goto sleep `ps axf | grep [c]hat | awk '{print "kill -9 " $1}' | sh` sleep(0.2) `ps axf | grep [p]ppd | awk '{print "kill -9 " $1}' | sh` sleep(0.2) Log4Ienso.log.P_ERR(" ========= Ghost port found ========") p = `ls -la /dev/ttyUSB*` puts(p) return 5 # need to signal to control program to sleep end # sometimes on resume the data port is not created # the only way to fix it is to go to sleep (unload drivers) # on resume it take upto 3 seconds before the port is created count = 0 while count < 12 do count += 1 if !File.exist?(getDataPort) sleep(1) # sometimes it takes time to create the ports next else break end end if !File.exist?(getDataPort) # test again Log4Ienso.log.P_ERR("#{Time.now.strftime("%H:%M:%S.%L")} TTY ports not found, the modem cannot be used") $gps_wakeup_flag = true return 5 # need to signal to control program to go to sleep end Log4Ienso.log.P_CLEAN("#{Time.now.strftime("%H:%M:%S.%L")} Modem USB Connected - can talk to A83 now") notify("lte/started") return 0 end #after the modem is booted run some basic checks and bring up the PPP interface #the ppp scripts are copied to the correct folders and sed with the correct port and apn values private def setupPPPInterface(provider) if File.exist?(@args.ltectrl.tty_data) @tty = File.open(@args.ltectrl.tty_data, File::RDWR) # flush every write. @tty.sync = true end if (provider == 'ROGERS-US') @apn = @args.ltectrl.network.rogers_us.apn elsif (provider == 'VERIZON') @apn = @args.ltectrl.network.verizon.apn elsif (provider == 'ATT') @apn = @args.ltectrl.network.atandt.apn elsif (provider == 'ROGERS-CAN') @apn = @args.ltectrl.network.rogers_can.apn elsif (provider == 'KPN') @apn = @args.ltectrl.network.kpn.apn else apn = @args.ltectrl.network.rogers-can.apn end dev = @args.ltectrl.tty_data[/(?:.(?!\/))+$/] dev=dev[1..dev.length] if dev != nil cmd = "/opt/wtc2.0/src/setup_ppp0 "+dev+" "+@apn #call the ppp setup script system( cmd ) end #Start the IP connection only if it does not exist? #Also set the nameserver, get network time and update hwclock #time needs to be updated to work with SSL certs def print_usb_ports() usb = `lsusb` pports =`ls -la /dev/ttyU*` Log4Ienso.log.P_ERR("USB state is #{usb} \n and Ports are #{pports}") end def connectBG96(provider) sleep 8 system("ifup wwan0") getNetworkAssignedIPAddress(Constant::INTERFACE_WWAN) return 0 end def connect(provider) Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} Starting connection to the network") r=0 if @network_ip == nil #cmd="echo at&d1 > "+@args.ltectrl.tty # make sure we are in command mode #system(cmd) if !File.exist?('/etc/ppp/peers/quectel-ppp') && !File.exist?('/etc/ppp/peers/quectel-chat-connect') setupPPPInterface(provider) end if !File.exist?('/dev/ppp') cmd="mknod /dev/ppp c 108 0" system(cmd) end Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} Dialing PPP will take 6 seconds") cmd="pppd call quectel-ppp" system(cmd) #system("echo 'nameserver 8.8.8.8' > /etc/resolv.conf") # better to have our own name resolution simcheck1 =`cat /etc/ppp/connect-errors` Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} simcheck1 before=#{simcheck1}") sleep(1) # before going any further check the ppp connection log for any errors # the below checks could be done only in DEBUG mode ??? TODO counter = 0 loop do sleep(1) counter += 1 #sleep(1) # wait for ppp to come up #simcheck1 =`cat /etc/ppp/connect-errors` #Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} simcheck1 after=#{simcheck1} , counter=#{counter}") rssi =`cat /etc/ppp/connect-errors | grep '+CSQ:' | cut -d ',' -f1 | cut -d ':' -f2` if rssi != nil rssi = rssi.strip $rssi = rssi if rssi.to_i > 0 end Log4Ienso.log.P_NOTICE("The RSSI is #{rssi}") conn =`cat /etc/ppp/connect-errors ` Log4Ienso.log.P_CLEAN("\ncounter=#{counter}\n cat /etc/ppp/connect-errors=#{conn}\n ") if rssi == '' or rssi.chomp == '99' or rssi.chomp=='199' if counter < 7 Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} NEXT TRY--------- rssi=#{rssi} , counter=#{counter}") #print_usb_ports() next #else # Log4Ienso.log.P_CLEAN("#{Time.now.strftime("%H:%M:%S.%L")} could not get rssi retry to connect") # return -1 end simcheck =`cat /etc/ppp/connect-errors | grep '+CME ERROR'` if simcheck.chomp == '+CME ERROR' Log4Ienso.log.P_ERR("#{Time.now.strftime("%H:%M:%S.%L")} SIM CARD ERROR - check if SIM is available or inserted") return (-1) end Log4Ienso.log.P_ERR("#{Time.now.strftime("%H:%M:%S.%L")} No network signal found ---- rssi=#{rssi} ") # TODO send this to LED display & i18n return(-2) else Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} Signal strength:" + rssi) end network =`cat /etc/ppp/connect-errors | grep '+COPS:' | cut -d ',' -f3` conn =`cat /etc/ppp/connect-errors ` Log4Ienso.log.P_CLEAN("\ncounter=#{counter} network \n cat /etc/ppp/connect-errors=#{conn}\n ") network = network.chomp if network == nil or network == '' if counter < 7 Log4Ienso.log.P_ERR("#{Time.now.strftime("%H:%M:%S.%L")} NEXT TRY--------- network=#{network} , counter=#{counter}") #print_usb_ports() next #else # Log4Ienso.log.P_CLEAN("#{Time.now.strftime("%H:%M:%S.%L")} could not get network ") # return -1 end #Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} network =#{network} ") end if network.length < 2 or network[0..4]=='+COPS' Log4Ienso.log.P_ERR("#{Time.now.strftime("%H:%M:%S.%L")} No network provider detected ! Is the SIM card activated ?") return(-3) else Log4Ienso.log.P_CLEAN("#{Time.now.strftime("%H:%M:%S.%L")} Connected to: " + network) #TODO send this to LED display & i18n #ret1 = getNetworkAssignedIPAddress2 #return -1 if ret1 == -1 getNetworkAssignedIPAddress(Constant::INTERFACE_PPP) end break end end r = addRoute #r = setTimeFromNetwork if r == 0 Log4Ienso.log.P_INFO("Connection established with internet") else Log4Ienso.log.P_INFO("Could not connect to internet") end return(r) end def addRoute if @network_ip != nil `route add default gw #{@network_ip}` Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} IP address is #{@network_ip}") return 0 end return 1 end # get time from the network def setTimeFromNetwork r=0 dtcheck=`date +%Y` #get the year dtcheck = dtcheck.chomp.strip if dtcheck == "1970" x=0 system("rdate -s #{@args.ltectrl.timeserver}") #setup time # rarely happens but must be handled while dtcheck == "1970" do system("rdate -s time.nist.gov") #setup time dtcheck=`date +%Y` dtcheck = dtcheck.chomp.strip if dtcheck == "1970" sleep(1+x) # rudimentary linear hysteresis x+=1 if(x>4) # break end else break end end if(x>4) Log4Ienso.log.P_INFO("Could not get the time, will not be able to send data on ssl") r=1 end system("hwclock --systohc") #update hardware clock end return r end #get the network assigned IP address def getNetworkAssignedIPAddress(type = 0) ip=nil count = 0 iplen = 0 while count < 12 do count += 1 #print_usb_ports() if type == Constant::INTERFACE_PPP ip_temp=`/sbin/ifconfig ppp0 | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1}' ` ip_temp2=`/sbin/ifconfig ppp0` elsif type == Constant::INTERFACE_WWAN ip_temp=`/sbin/ifconfig wwan0 | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1}' ` ip_temp2=`/sbin/ifconfig wan0` end iplen = ip_temp.to_s.chomp.strip.length if iplen == 0 Log4Ienso.log.P_CLEAN("#{Time.now.strftime("%H:%M:%S.%L")} Could not find IP address or ppp0 interface") Log4Ienso.log.P_INFO("ip_temp2=#{ip_temp2.to_s}") sleep(1) #count) next else ip = ip_temp @network_ip =ip $ip_failed_cntr = 0 #$ip_reset_cntr = 0 Log4Ienso.log.P_CLEAN("#{Time.now.strftime("%H:%M:%S.%L")} Found IP adress #{ip}") break end end if (count >= 12) notify("lte/getting_ip_failed") Log4Ienso.log.P_ERR("#{Time.now.strftime("%H:%M:%S.%L")} getting IP adress failed send notification to reset lte") sleep 0.1 end return ip end def getNetworkAssignedIPAddress2 ip=nil count = 0 iplen = 0 while count < 12 do count += 1 #print_usb_ports() ip_temp=`/sbin/ifconfig ppp0 | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1}' ` ip_temp2=`/sbin/ifconfig ppp0 ` if count > 4 if ip_temp2.to_s == '' or ip_temp2.to_s == nil Log4Ienso.log.P_CLEAN("#{Time.now.strftime("%H:%M:%S.%L")} Could not find ppp0 ip_temp2=#{ip_temp2.to_s}") return -1 end end iplen = ip_temp.to_s.chomp.strip.length if iplen == 0 Log4Ienso.log.P_CLEAN("#{Time.now.strftime("%H:%M:%S.%L")} Could not find IP address or ppp0 interface") Log4Ienso.log.P_INFO("ip_temp2=#{ip_temp2.to_s}") sleep(1) #count) next else ip = ip_temp @network_ip =ip Log4Ienso.log.P_CLEAN("#{Time.now.strftime("%H:%M:%S.%L")} Found IP adress #{ip}") break end end if (count >= 12) notify("lte/getting_ip_failed") Log4Ienso.log.P_ERR("#{Time.now.strftime("%H:%M:%S.%L")} getting IP adress failed send notification to reset lte") sleep 0.1 end return ip end #get the bytes rcvd def getBytesReceivedInThisSession txb =`/sbin/ifconfig ppp0 | grep 'RX bytes:' | cut -d: -f2 | awk '{ print $1}'` return txb end #get the bytes sent def getBytesTransmittedInThisSession txb =`/sbin/ifconfig ppp0 | grep 'RX bytes:' | cut -d: -f3 | awk '{ print $1}'` return txb end #if the sim card or the provider change #then reset the scripts def resetPPPInterface() system("rm -rf /etc/ppp/") # remove all details of the apn system("rm -rf #{@cfolder}") # clear the imei/iccid numbers Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} PPP interface reset. New network provider/ SIM card can now be used") end def getLteConfigPath return @cfolder end def getLteConfigFile return @cfile end def getSessionTokenFile return @cfolder+ "/" + @args.ltectrl.lte_config.token_file end def getCommandPort return @args.ltectrl.tty_command end def getDataPort return @args.ltectrl.tty_data end def getAPIEndPoint return @args.ltectrl.cloud_service_provider.zipit.end_point end def getLogName return @args.ltectrl.log_name end def startSleep #`echo at+cfun=4 > #{getCommandPort}` # system(%Q(/opt/wtc2.0/src/sleep.sh)) if$model == "impulse" # system(%Q(/opt/wtc2.0/src/sleep_primos.sh)) if$model == "primos" end end if __FILE__ == $0 begin $model = "primos" if $model == "impulse" m=LteModem.new(YAML.load(File.read("/opt/wtc2.0/src/wtc2_config_v0.0.2-a.yaml")).to_hashugar) Log4Ienso.log.P_INFO("ready to enable modem") m.enableModem(0) Log4Ienso.log.P_INFO("edit the correct network name for testing - default is ROGERS-US") m.connect("ROGERS-US") elsif $model == "primos" m=LteModem.new(YAML.load(File.read("/opt/wtc2.0/src/wtc2_config_v0.0.2-a.yaml")).to_hashugar) Log4Ienso.log.P_INFO("ready to enable modem") m.enableModemBG96(0) Log4Ienso.log.P_INFO("edit the correct network name for testing - default is ROGERS-US") m.connectBG96("ROGERS-US") end #sleep(5) #Log4Ienso.log.P_INFO("Now shutting down modem") #m.shutdownModem() #cmd="echo at&d1 >/dev/ttyUSB2; echo ati > /dev/ttyUSB2" #system(cmd) rescue Exception => e Log4Ienso.log.P_INFO("Exception: #{e}") Log4Ienso.log.P_INFO(e.backtrace) end end opt/wtc2.0/src/env.rb0000644000175200017520000001165213557057144015037 0ustar bushnellbushnellclass Env @env = nil def initialize(default_env) @default_env = default_env @env_path = File.dirname(__FILE__) + "/" + @default_env.path + @default_env.name if( File.exist?(@env_path) == false) reset_default() else load() end if( @env.is_a?(Hash) == false) reset_default() end end def get_env_path File.dirname(__FILE__) + "/" + @default_env.path + "/" end def save_env(id, idx) begin splitid=id.split('.') if(splitid[1] != nil) @env[splitid[0]] [splitid[1]] ['selected'] = @env[splitid[0]] [splitid[1]]['candidate'][idx] if @env[splitid[0]] [splitid[1]]['candidate'][idx] != nil else @env[id]['selected'] = @env[id]['candidate'][idx] if @env[id]['candidate'][idx] != nil end File.open(@env_path, "w+") do |file| YAML.dump(@env,file) end $menu_values_changed = true $lastupdatetime = Time.now.strftime("%Y-%m-%dT%H:%M:%S") rescue puts("error in env") end end def save_env_val(id, val) begin splitid=id.split('.') if(splitid[1] != nil) if @env[splitid[0]] [splitid[1]] ['candidate'] == nil @env[splitid[0]] [splitid[1]] ['selected'] = val else @env[splitid[0]] [splitid[1]] ['candidate'].each do |candid| @env[splitid[0]] [splitid[1]] ['selected'] = val if candid == val end end else if @env[id]['candidate'] == nil @env[id]['selected'] = val else @env[id]['candidate'].each do |candid| @env[id]['selected'] = val if val == candid end end end File.open(@env_path, "w+") do |file| YAML.dump(@env,file) end $menu_values_changed = true $lastupdatetime = Time.now.strftime("%Y-%m-%dT%H:%M:%S") rescue puts("error") end end def load(env_path=nil) if(env_path == nil) env_path = @env_path end @env = YAML.load(File.open(env_path, 'r')) end def reset_default File.open(@env_path, "w+") do |file| file.write @default_env.to_hash.to_yaml end load() end def get_env(id) begin env = nil splitid=id.split('.') if(splitid[1] != nil) env = @env[splitid[0]] [splitid[1] ]['selected'] else if(@env[id] != nil) env = @env[id]['selected'] end end env rescue puts("error in env") end end def get_candidate(id) begin @env[id]['candidate'] if @env[id] != nil rescue puts("error in env") end end def get_candidate2(id) begin splitid=id.split('.') #puts "--------- splitid = #{splitid}" @env[splitid[0]] [splitid[1]] ['candidate'] if @env[splitid[0]] != nil rescue puts("error in env") end end def get_candidate_count(id) begin splitid=id.split('.') if(splitid[1] != nil) @env[splitid[0]] [splitid[1]] ['candidate'].count if @env[splitid[0]] != nil else @env[id]['candidate'].count if @env[id] != nil end rescue puts("error in env") end end def get_selected_idx(id) begin env_cand = get_candidate(id) idx = nil if(env_cand != nil) env_select = get_env(id) for i in 0..(env_cand.length - 1) if(env_cand[i] == env_select) idx = i break end end end idx rescue puts("error in env") end end def get_env_value(id) begin val = get_env(id) result = 0; if(val != nil) split_val = val.split('_') if(split_val[1] != nil) mult = case split_val[1] when 'second' then 1 when 'minute' then 60 when 'hour' then 3600 when 'copy' then 1 else nil end if(mult != nil) result = split_val[0].to_i * mult else result = val end else result = val end end result rescue puts("error in env") end end end def str_to_latitude(string) #0123456789012 #N 00°00'00.0" {:azimuth=>string[0],:degree=>string[2..3].to_i, :minute=>string[5..6].to_i, :second=>string[8..11].to_f} end def str_to_longitude(string) #0123456789012 #N 00°00'00.0" {:azimuth=>string[0],:degree=>string[2..4].to_i, :minute=>string[6..7].to_i, :second=>string[9..12].to_f} end opt/wtc2.0/src/enablehotspot.sh0000755000175200017520000000125013557057144017121 0ustar bushnellbushnell#!/bin/sh /etc/init.d/S80dnsmasq stop #check if driver loaded #l ="$(lsmod | grep 8723bs | wc -l)" #if [ -z "$l" ] #then # "$(modprobe -v 8723bs)" #else # echo "driver loaded" #fi WLAN="$(ifconfig -a | cut -d" " -f1 | grep w | head -1)" echo $WLAN rand="$(ifconfig -a | tr -s " "| grep w | cut -d" " -f5 | head -1)" n="Bushnell" SSIDNAME=$n$rand cp -r /opt/wtc2.0/src/hs-scripts/* /etc/ sed -i "s/wlan0/$WLAN/g" /etc/hostapd.conf sed -i "s/wlan0/$WLAN/g" /etc/dnsmasq.conf sed -i "s/BushnellCam/$SSIDNAME/g" /etc/hostapd.conf ifconfig $WLAN up 192.168.44.1 netmask 255.255.255.0 sleep 0.1 /usr/sbin/dnsmasq -C /etc/dnsmasq.conf /usr/sbin/hostapd -B /etc/hostapd.confopt/wtc2.0/src/picture_manager.rb0000644000175200017520000004664013557057144017421 0ustar bushnellbushnellrequire 'thread' require 'dem' class PictureManager include EventSource MAX_ERROR = 3 def initialize(config) @config = config if(@config == nil) @pic_path = "/media/photos/DCIM/" #@config.pic_path @thumb_path = "/media/photos/thumb/" #@config.thumb_path @input_path = "/tmp/" @max_error_count = 50 @log = Syslog::Logger.new("picman") else @pic_path = @config.pic_path @thumb_path = @config.thumb_path @input_path = @config.input_path @max_error_count = @config.max_error_count @log = Syslog::Logger.new(@config.log_name) end @mutex_pic_num = Mutex.new @last_pic_time =nil @thumbs_waiting = Queue.new @thumbs_resend_waiting = Queue.new @thumbs_sending = [] @errorCount = 0 @num_of_pic = 0 @num_of_vid = 0 @status = false @dispslace = 0 @thread_h = nil #if A83 resets the queue is cleared, lets push it with remaining thumbs count = 0 #`find /media/photos/thumb/ -name '*' -type f`.split.each do |file_name| Dir["/media/photos/thumb/*.jpg"].each do |file_name| @thumbs_waiting << file_name Log4Ienso.log.P_INFO("ADDED #{file_name} to Q |||||||||| size is #{@thumbs_waiting.size}") count+=1 if count >50 count = 0 break end end #@next_pic_num = nil #@next_vid_num = nil #@next_pic_vid_num = nil Log4Ienso.log.P_INFO("Initialize Success") end def start() @thread_h = Thread.new{ loop do begin status = mounted? if(status == true) dispslace = diskSpace(); end if(@status != status) @status = status if(status) notify("sdcard/inserted" , :begin) insert_sd(true) @dispslace = 0 #this is to re read the disk space after each insert notify("sdcard/inserted" , :end) else notify("sdcard/removed" , :begin) insert_sd(false) notify("sdcard/removed" , :end) end end sleep(0.1) rescue Exception => e Log4Ienso.log.P_ERR("PICMAN Exception: #{e}") Log4Ienso.log.P_ERR(e.backtrace) @log.error(e.backtrace) end end } if(@thread_h == nil) end def stop() if(@thread_h != nil) Thread.kill(@thread_h) @thread_h.join() @thread_h = nil end end def diskSpace() #df = `df -m /dev/mmcblk1p1`.split(/\b/) total = `df -m /dev/mmcblk1p1| tail -1 | tr -s " " | cut -d" " -f2` #df[22].to_i free = `df -m /dev/mmcblk1p1| tail -1 | tr -s " " | cut -d" " -f4` #df[24].to_i total = total.to_i * 1024 free = free.to_i * 1024 diskSpace = {:total=>total, :free=>free} if(@dispslace != diskSpace) @dispslace = diskSpace notify("sdcard/diskSpace" , diskSpace) end diskSpace end def mounted?() # the regex comparison (=~) returns the location of the match (positive # integer) or nil if there is not match not (`mount` =~ %r{/media/photos}).nil? end def insert_sd(isInsert) Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")}====== insert_sd before ==== @mutex_pic_num") @mutex_pic_num.synchronize{ Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")}====== insert_sd after ==== @mutex_pic_num") @errorCount = 0 if(isInsert) #@next_pic_num = find_pic_num() #@next_vid_num = find_vid_num() #@next_pic_vid_num = find_pic_vid_num() find_resend_pic() if !File::directory?(@thumb_path) Dir.mkdir(@thumb_path) end if !File::directory?(@pic_path) Dir.mkdir(@pic_path) end #@num_of_pic = get_num_photos() #@num_of_vid = get_num_videos() @num_of_pic_vid = get_num_photos_videos() else @thumbs_waiting.clear() @thumbs_resend_waiting.clear() @thumbs_sending = [] #@next_pic_num = nil @num_of_pic = 0 #@next_vid_num = nil @num_of_vid = 0 #@next_pic_vid_num = nil @num_of_pic_vid = 0 end } end def enter_sleep(issleep,mode) Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")}====== enter sleep before ==== @mutex_pic_num") @mutex_pic_num.synchronize{ Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")}====== enter sleep after ==== @mutex_pic_num") @errorCount = 0 if(issleep) @thumbs_resend_waiting.clear() else @thumbs_sending = [] @thumbs_waiting.clear() @thumbs_resend_waiting.clear() Log4Ienso.log.P_NOTICE("--------------------------------------------------------------") if mode == 0 #read the sd card find_resend_pic() end Log4Ienso.log.P_NOTICE("--------------------------------------------------------------") end } #if @next_pic_vid_num != nil end def resend_pic Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")}====== resend pic before ==== @mutex_pic_num") @mutex_pic_num.synchronize{ Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")}====== resend pic after ==== @mutex_pic_num") if(@thumbs_resend_waiting.size() == 0) find_resend_pic() if(@thumbs_resend_waiting.size != 0) @thumbs_waiting << @thumbs_resend_waiting.pop if(@thumbs_waiting.size == 0) end @errorCount = 0 if @errorCount != 0 end } end #def get_pic_count # @next_pic_num #end # This method allows the execution of ruby code in a subprocess. # It is useful for long running IO bound code such as Dir[] for large # quantities of files. Dir[] will invoke the GIL and cause all Threads # to block. # # This method accepts a block and will return the return value of the # last expresion in the block. # Example: # # files = in_subprocess{ # Dir['/tmp/*'] # } # # This method blocks the flow of execution until the block returns. def in_subprocess rd, wr = IO.pipe pid = fork if not pid.nil? wr.close ret = JSON.parse('[' + rd.read + ']')[0] #puts rd.read rd.close Process.wait ret else rd.close wr.write yield.to_json wr.close Kernel.exit! end end def delete_oldest_pic() oldest_pic = Dir.glob(@pic_path + "*.jpg").min_by {|f| File.mtime(f)} #oldest_pic = in_subprocess{ # Dir.glob(@pic_path + "WTC20_*.jpg").min_by {|f| File.mtime(f)} #} if (oldest_pic != nil) FileUtils.rm(oldest_pic) end system('sync') dispslace = diskSpace(); @num_of_pic = get_num_photos() end def delete_oldest_vid() oldest_vid = Dir.glob(@pic_path + "*.mp4").min_by {|f| File.mtime(f)} #oldest_vid = in_subprocess{ # Dir.glob(@pic_path + "WTC20_*.mp4").min_by {|f| File.mtime(f)} # } if (oldest_vid != nil) FileUtils.rm(oldest_vid) end dispslace = diskSpace(); @num_of_vid = get_num_videos() end def save_picture(id, json, isthumbupload = true, day_ngit='D') Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} ***** STARTING PICTURE SAVE ********") path = @input_path + "#{id}_out_" tmp_arr = Dir[path + "thumb*.jpg"] my_dir = [] tmp_arr.each do |fil| num_re = /#{id}_out_thumb_(?\d+)\.jpg$/ fil_match = num_re.match(fil) next if fil_match == nil my_dir << [fil, fil_match[:num].to_i] end my_dir.sort! { |a,b| a[1] <=> b[1] } if (my_dir.count == 0) Log4Ienso.log.P_WARN("Can't find picture image at path=#{path}.") end my_dir.each do |thumb| thumbname = thumb[0] picname = thumbname.split("_thumb") picname = picname[0] + picname[1] #picname = '/etc/img.jpg' #thumbname = '/etc/thumb.jpg' pic_time = Time.now if @last_pic_time == pic_time.to_i pic_time += 1 end @last_pic_time = pic_time.to_i dest_thumb_jpg = "#{@thumb_path}#{pic_time.strftime("%y%m%d%H%M%S")}P.jpg" dest_jpg = "#{@pic_path}#{pic_time.strftime("%y%m%d%H%M%S")}.jpg" Log4Ienso.log.P_INFO("In thumb file = #{thumbname}") Log4Ienso.log.P_INFO("In pic file = #{picname}") Log4Ienso.log.P_INFO("Out thumb file = #{dest_thumb_jpg}") Log4Ienso.log.P_INFO("Out pic file = #{dest_jpg}") if(isthumbupload == true) cmd = "makeExif " + thumbname +" " + dest_thumb_jpg +" '" + json +"'" system(cmd) if(@errorCount < @max_error_count) Log4Ienso.log.P_INFO("====== thumb added to queue = #{dest_thumb_jpg}") @thumbs_waiting << dest_thumb_jpg notify("modem/continueupload") end Log4Ienso.log.P_INFO("Save Thumb [#{thumbname}]") end cmd = "makeExif " + picname +" " + dest_jpg +" '" + json +"'" system(cmd) Log4Ienso.log.P_INFO("Save picture [#{dest_jpg}]") end #Log4Ienso.log.P_YELLOW("#{Time.now.strftime("%H:%M:%S.%L")} ***** ENDING PICTURE SAVE BEFORE SYNC********\n") #system('sync') Log4Ienso.log.P_YELLOW("#{Time.now.strftime("%H:%M:%S.%L")} ***** ENDING PICTURE SAVE AFTER SYNC********\n") my_dir = Dir["/tmp/#{id}*.jpg"] my_dir.each do |filename| FileUtils.rm(filename) end @num_of_pic_vid = get_num_photos_videos() Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} ***** ENDING PICTURE SAVE ********") end def save_video(id, json, movie_resolution, isthumbupload = true, day_ngit='D', hybrid = 'off', hybrid_num =200) path = @input_path + "#{id}_rec" my_dir = Dir[path+".mpg"] my_dir.sort! Log4Ienso.log.P_NOTICE("In /tmp/ file = #{my_dir}") if (my_dir.count == 0) Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} Can't find video image at path=#{path}.") end my_tmp = `find /tmp/ -name 'tm*.mpg'`.split my_tmp.each do |filename| FileUtils.rm(filename) end my_dir.each do |picname| #Log4Ienso.log.P_NOTICE("In thumb file = #{thumbname}") pic_time = Time.now if @last_pic_time == pic_time.to_i pic_time += 1 end @last_pic_time = pic_time.to_i dest_thumb_jpg = "#{@thumb_path}#{pic_time.strftime("%y%m%d%H%M%S")}V.jpg" dest_mpg = "#{@pic_path}#{pic_time.strftime("%y%m%d%H%M%S")}.mp4" dest_hybrid = "#{@pic_path}#{pic_time.strftime("%y%m%d%H%M%S")}.jpg" Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} In video file = #{picname}") Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} Out thumb file = #{dest_thumb_jpg}") Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} Out hybrid file = #{dest_hybrid}") Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} Out video file = #{dest_mpg}") cmd = "cp " + picname + " " + dest_mpg Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} ========================= !! cmnd=#{cmd}.") system(cmd) if(isthumbupload == true) cmd = "makeExif " + path + "_thumb_#{hybrid_num}.jpg" + " " + dest_thumb_jpg +" '" + json +"'" Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} ========================= !! cmnd=#{cmd}.") system(cmd) end if(hybrid == 'on') cmd = "makeExif " + path + "_hybrid_#{hybrid_num}.jpg" + " " + dest_hybrid +" '" + json +"'" Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")} ========================= !! cmnd=#{cmd}.") system(cmd) end if(@errorCount < @max_error_count) Log4Ienso.log.P_INFO("====== thumb added to queue = #{dest_thumb_jpg}") @thumbs_waiting << dest_thumb_jpg notify("modem/continueupload") end Log4Ienso.log.P_INFO("#{Time.now.strftime("%H:%M:%S.%L")} Save video [#{dest_mpg}]") #FileUtils.rm("/tmp/tmp.mpg") end system('sync') #my_dir = Dir["/tmp/#{id}*.mpg"] my_dir = Dir["/tmp/*.mpg"] my_dir.each do |filename| FileUtils.rm(filename) end @num_of_vid = get_num_photos_videos() end def get_thumb_for_send_server_test thumb = nil count = 0 @mutex_pic_num.synchronize{ if @thumbs_waiting.size == 0 `find /media/photos/thumb/ -name '*'`.split.each do |file_name| @thumbs_waiting << file_name Log4Ienso.log.P_INFO("ADDED #{file_name} to Q |||||||||| size is #{@thumbs_waiting.size}") count+=1 if count >50 count = 0 break end end end if(@thumbs_waiting.size != 0) thumb = @thumbs_waiting.pop end } return thumb end def get_thumb_for_send_server thumb = nil #Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")}====== get thumb before ==== @mutex_pic_num") @mutex_pic_num.synchronize{ #Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")}====== get thumb after ==== @mutex_pic_num") if(@thumbs_waiting.size != 0) thumb = @thumbs_waiting.pop @thumbs_sending << thumb elsif(@thumbs_resend_waiting.size != 0) thumb = @thumbs_resend_waiting.pop @thumbs_sending << thumb else thumb = nil end } #if thumb == nil # thumb = @thumbs_waiting.pop # @thumbs_sending << thumb #end #puts "SENT SERVER QUEUE SIZE #{@thumbs_waiting.size + @thumbs_resend_waiting.size}" thumb end def submit_thumb(thumb, result) filedelete=1 begin Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")}====== submit before ==== @mutex_pic_num") @mutex_pic_num.synchronize{ Log4Ienso.log.P_NOTICE("#{Time.now.strftime("%H:%M:%S.%L")}====== submit after ==== @mutex_pic_num") if(@thumbs_sending.include?(thumb) && File.exist?(thumb)) @thumbs_sending.delete(thumb) if result == 0 FileUtils.rm(thumb) @errorCount = 0 else @errorCount+=1 Log4Ienso.log.P_INFO "SEND SERVER ERROR!!!!! #{@errorCount}" notify("modem/uploaderror") if(@errorCount >= @max_error_count) @thumbs_resend_waiting.clear() @thumbs_waiting.clear() end end filedelete=0 else Log4Ienso.log.P_INFO "SUBMIT THUMB ERROR #{thumb}" end } rescue Exception=>e Log4Ienso.log.P_INFO "Failed to delete #{thumb} error= #{e.backtrace}" ensure if filedelete == 1 `rm #{thumb}` end end end # This methods returns the number of photos currently stored on the storage device. def get_num_photos #pics = `find #{@pic_path} -name 'WTC20_*.*'`.split #pics = Dir[@pic_path + "WTC20_*.jpg"] pics = Dir[@pic_path + "*.jpg"] num = pics.size() Log4Ienso.log.P_INFO("get_num_photos #{num}") notify("sdcard/num_pic" , num) num end def get_num_videos #vids = `find #{@pic_path} -name 'WTC20_*.*'`.split #vids = Dir[@pic_path + "WTC20_*.mp4"] vids = Dir[@pic_path + "*.mp4"] num = vids.size() Log4Ienso.log.P_INFO("get_num_videos #{num}") notify("sdcard/num_vid" , num) num end def get_num_photos_videos #pics_vids = `find #{@pic_path} -name 'WTC20_*.*'`.split #pics_vids = Dir["#{@pic_path}/WTC20_*.*"] pics_vids = Dir["#{@pic_path}/*.*"] num = pics_vids.size() Log4Ienso.log.P_INFO("get_num_photos_videos #{num}") notify("sdcard/num_pic_vid" , num) num end =begin def find_pic_vid_num pv_num_re = /WTC20_(?\d+)\.(?:jpg|mp4)/ pic_vid = Dir[@pic_path + "WTC20_*.*"] #pic_vid = in_subprocess{ # Dir[@pic_path + "WTC20_*.*"] #} max_num = 0 pic_vid.each { |pv| re_match = pv_num_re.match(pv) next if re_match == nil temp = re_match[:num].to_i + 1 max_num = temp if temp > max_num } @next_pic_vid_num = max_num end =end def find_resend_pic #resend_thumbs = Dir[@thumb_path + "WTC20_*.jpg"] #resend_thumbs.sort!{|x,y|y<=>x} #Log4Ienso.log.P_INFO "re send thumb to server" #resend_thumbs.each do |val| # @thumbs_resend_waiting.push(val) #end count = 0 @thumbs_waiting.clear #`find /media/photos/thumb/ -name 'WTC20_*.*'`.split.each do |file_name| #Dir["/media/photos/thumb/WTC20_*.*"].each do |file_name| Dir["/media/photos/thumb/*.jpg"].each do |file_name| @thumbs_waiting << file_name Log4Ienso.log.P_INFO("ADDED #{file_name} to Q |||||||||| size is #{@thumbs_waiting.size}") count +=1 if count > 50 count=0 break end end end private def debug loop do val = @thumbs.pop(true) Log4Ienso.log.P_INFO(val) end end =begin def get_pic_vid_num_and_increase num = nil @mutex_pic_num.synchronize{ num = @next_pic_vid_num @next_pic_vid_num += 1 if (num != nil) } num end =end end if $0 == __FILE__ require 'json' exifTag = Hash.new() exifTag[:Make] = "IENSO" exifTag[:Model] = "WTC2.0" exifTag[:DateTimeOriginal] = Time.now.strftime("%Y:%m:%d %H:%M:%S") #@nmea.dateTime #exifTag[:DateTimeOriginal] = @nmea.dateTime # it's Example how to insert unsupported Tag # exifTag[:DateTime] = {:ifdType => 1, :tagId => 132,:tagType =>2 , :value => @nmea.dateTime }; json = JSON.generate(exifTag) pic = PictureManager.new(nil) pic.save_picture(1, json) end opt/wtc2.0/src/sleep_primos.sh0000755000175200017520000000031513557057144016754 0ustar bushnellbushnell#!/bin/sh ifdown wwan0 if [ ! -d /sys/class/gpio/gpio116 ] then echo 116 > /sys/class/gpio/export echo out > /sys/class/gpio/gpio116/direction fi echo 0 > /sys/class/gpio/gpio116/value exit 0 opt/wtc2.0/src/quectel.rb0000644000175200017520000011112513557057144015705 0ustar bushnellbushnellrequire 'syslog/logger' require 'date' require 'time' require 'debug' require 'serialport' # helper class to clean up strings class String def strip_control_char() chars.each_with_object("") do |char, str| str << char unless char.ascii_only? and (char.ord < 32 or char.ord == 127) end end def strip_control_and_extended_char() chars.each_with_object("") do |char, str| str << char if char.ascii_only? and char.ord.between?(32,126) end end def is_i? !!(self =~ /\A[-+]?[0-9]+\z/) end end =begin Press CTRL-A Z for help on special keys AT+QICSGP=1,1,“UNINET”,“”,“”,1 //Configure PDP context 1, APN is “UNINET” for China Unicom. OK AT+QIACT=1 //Activate PDP context 1. OK //Activate successfully. AT+QIACT? //Query the state of PDP context. +QIACT: 1,1,1,“10.82.100.192” OK AT+QFTPCFG=“contextid”,1 //Set the PDP context ID as 1. The PDP context ID must be activated before. OK //Step 2: Configure user account and transfer settings. AT+QFTPCFG=“filetype”,1 //Set file type as Binary. OK AT+QFTPCFG=“transmode”,1 //Set transfer mode as Passive mode. OK AT+QFTPCFG=“rsptimeout”,90 //Set response timeout value. OK //Step 3: Login to FTP server. AT+QFTPOPEN=“ftp2.quectel.com” OK +QFTPOPEN: 0,0 Quectel at+qftpcwd="/Polly1" OK +QFTPCWD: 627,550 at+qftpget="1234.txt","UFS:1234.txt" //Download a file from FTP server OK +QFTPGET: 627,550 at+qflst="UFS:1234*" +CME ERROR: Fail to list the file at+qflst="UFS:*" +QFLST: "clientkey.key",1675 +QFLST: "1234.txt",8 +QFLST: "cacert.crt",1758 +QFLST: "clientcert.crt",1224 OK =end # This class provides access to the AT command set of Quectel EC21-25 family # Note that the chip suports multiple ports and modes # the data mode is on ttyUSB2 amd command mode is on ttyUSB3 or vica versa # all AT commands need "command" mode class QuectelATCommands include EventSource RESULT_CODES = [ "OK", "CONNECT", "RING", "NO_CARRIER", "ERROR", "NO_DIALTONE", "BUSY", "NO_ANSWER" ] # Create an instance of the class. # params (3 params) tty - eg /dev/ttyUSB3 , logfile name and lteconfig file # - args: This parameter is meant to contain the application's config file content. See config.yaml for details. See also Control for how to instantiate this class. def initialize(tty,logfile,configfile) # Intialize the data bus @log = Syslog::Logger.new(logfile) @tty = tty @config_file =configfile @echostate =0 # AT commands will echo when 0 @imei=nil @iccid=nil @rssi=0 @slowclockenabled=0 @scale0rssi=@scale1rssi=0 @mutex_send_at_cmnd = Mutex.new if !File.exists?(@tty) Log4Ienso.log.P_INFO("Interface not setup, run lte.rb first") #exit(0) not required here, checking it in main end # moving this to sleep.sh as this can take 6 seocnds #sendATCmdRaw("AT+QSCLK=0") #if @slowclockenabled==0 # setSlowClock() #end end def setSlowClock() count = 0 sendATCmdRaw("AT+QSCLK=1") # enable slow clock while getSlowClock() == 0 do sendATCmdRaw("AT+QSCLK=1") # enable slow clock sleep(0.3) count+=1 if count > 5 @slowclockenabled=0 break end end @slowclockenabled=1 end def getSlowClock() r = sendATCmdRaw("AT+QSCLK?") if (r == nil) return 0 end if r.include? "1" return 1 elsif r.include? "0" return 0 else return 0 end end # echo needs to be removed in order to correctly parse result # however if the instance of the class is restarted the behaviour of ATE0 # when echo is off is inconsitent. Therefore best not to use this command #send any AT command as defined by Quectel # the result will be raw ascii, will need custom parsing def sendATCmdRaw(command) r = sendATcmd(command) Log4Ienso.log.P_INFO("Raw command return is " + r.to_s) return r end # faster way to get imei and iccid as can pick up cache data def getIMEIandICCID(starttype) imei=iccid=nil found = 0 if File.exists?(@config_file) begin imei = `cat #{@config_file} | head -1` iccid = `cat #{@config_file} | tail -1` imei = imei.chomp iccid = iccid.chomp rescue Exception=>e Log4Ienso.log.P_INFO("Error in reading imei/iccid from file" + e.to_s) Log4Ienso.log.P_INFO("[LTE] Error in reading imei/iccid from file") ensure if imei!="" and iccid!="" and imei.is_i? and iccid.is_i? Log4Ienso.log.P_INFO("Got IMEI and ICCID from file") Log4Ienso.log.P_INFO("[LTE] Got IMEI & ICCID from file") found=1 end end end if starttype == Constant::COLD_BOOT || found == 0 Log4Ienso.log.P_INFO("COLD BOOT - will sleep for another 10 seconds") sleep(10) imei = getIMEI() imei = imei.tr("^0-9", '') if imei != nil iccid =getICCID() iccid = iccid.tr("^0-9", '') if iccid != nil if( (imei == nil) || (iccid == nil) ) imei=iccid=nil return imei,iccid end if imei!="" and iccid!="" and imei.is_i? and iccid.is_i? `echo #{imei} > #{@config_file}` `echo #{iccid} >> #{@config_file}` Log4Ienso.log.P_INFO("Got IMEI & ICCID from hardware") Log4Ienso.log.P_INFO("[LTE] Got IMEI & ICCID from hardware") else Log4Ienso.log.P_INFO("Failed to read hardware for IMEI and ICCID: #{imei}, #{iccid}") Log4Ienso.log.P_INFO("[LTE] Failed to read hardware for IMEI and ICCID") imei=iccid=nil end end return imei,iccid end # direct way to get imei, but with several tries as sometimes call fails def getIMEI() imei = execATCmdIMEI c=0 while (imei==nil) sleep(1) imei = execATCmdIMEI c+=1 if c >5 break end end return imei end def getIMSI() imsi = execATCmdCIMI c=0 while (imsi==nil) sleep(1) imsi = execATCmdCIMI c+=1 if c >5 break end end return imsi end def readSlowClock return @slowclockenabled end # direct way to get iccid, but with several tries as sometimes call fails def getICCID() c=0 iccid = execATCmdICCID while (iccid==nil) sleep(1) iccid=execATCmdICCID c+=1 if c > 5 break end end return iccid end def checkIfEphermisDataValid cmd = "AT+QGPSXTRADATA?" r =sendATcmd(cmd) Log4Ienso.log.P_INFO(r) return r end def waitForUnsolicited(message, len, timeoutms) found = false reply = "" @mutex_send_at_cmnd.synchronize{ begin sp = SerialPort.new(@tty, 115200) sp.read_timeout = timeoutms reply = sp.read(len) if reply != nil Log4Ienso.log.P_INFO("waitForUnsolicited: [#{reply}]") reply = reply.strip_control_and_extended_char() end sp.close end } if reply != nil and reply == message found = true end return found end def gpsGetXtraTimeString() # The camera time is set using localtime, but the timezone in linux is not updated # so Time.now.utc will always == Time.now # So to Work around this(Hack) use the global camera_timezone tz = $camera_timezone.to_i if tz == 0 Log4Ienso.log.P_ERR("gpsGetXtraTimeString: TZ may NOT be set") end now = Time.now utc = Time.now.utc utc = utc + (tz * 60 * 60) dtstr = utc.strftime("%Y/%m/%d,%H:%M:%S") Log4Ienso.log.P_NOTICE("gpsGetXtraTimeString: local[#{now}] utc[#{utc}] xtra[#{dtstr}]") return dtstr end def updateGPSFromFTP(ftpserver, ftpuser, ftp_password, apn, pdp) ret = false r1 = sendATCmdRaw("at+qgpsxtradata?") =begin utctime= `curl -v --silent https://google.com/ 2>&1 \ | grep Date | sed -e 's/< Date: //' ` utctime=utctime.chomp.strip Log4Ienso.log.P_INFO("utctime is " + utctime) dt = `date -u -D'#{utctime}' +%Y/%m/%d,%T` #note in busbox the switch is -D, in ubuntu and others -d dt = dt.chomp.strip =end cntx = 15 sendATcmd("AT+QICSGP=#{cntx},1,\"#{apn}\",\"\",\"\",#{pdp}") sleep 0.5 sendATcmd("AT+QIACT=#{cntx}") sleep 0.5 sendATcmd("AT+QIACT?") sleep 0.5 sendATcmd("AT+QFTPCFG=\"contextid\",#{cntx}") sendATcmd("AT+QFTPCFG=\"account\",\"#{ftpuser}\",\"#{ftp_password}\"") sendATcmd("AT+QFTPCFG=\"filetype\",1") sendATcmd("AT+QFTPCFG=\"transmode\",1") sendATcmd("AT+QFTPCFG=\"rsptimeout\",90") Log4Ienso.log.P_MAGENTA("Downloading XTRA data from FTP...") #echo "connecting to FTP" sendATcmd("AT+QFTPOPEN=\"#{ftpserver}\",21", "+QFTPOPEN:") #Log4Ienso.log.P_NOTICE("Login to FTP server OK") #echo "downloading extra2.bin file" sendATcmd("at+qftpget=\"xtra2.bin\", \"RAM:xtra2.bin\"", "+QFTPGET:") #echo "closing ftp connection" sendATcmd("at+qftpclose") sendATcmd("at+qgpsend") Log4Ienso.log.P_MAGENTA("Loading XTRA data into GPS...") dt = gpsGetXtraTimeString() #echo "setting time as: $utctime" sendATcmd("AT+QGPSXTRATIME=0,\"#{dt}\",1,1,3500") #echo "checking if donwload is ok" sendATcmd("AT+QFLST=\"RAM:*\"") #echo "updating gnss" sendATcmd("AT+QGPSXTRADATA=\"RAM:xtra2.bin\"") sleep 5.0 #echo "enabling gps extra" sendATcmd("at+qgpsxtra=1") #echo "deleting file" sendATcmd("AT+QFDEL=\"RAM:xtra2.bin\"") #{}`/opt/wtc2.0/src/gnns-update.sh #{ftpserver} #{ftpuser} #{ftp_password} #{apn} #{pdp} #{utctime}` r2 = sendATCmdRaw("at+qgpsxtradata?") if r1 != r2 ret = true else Log4Ienso.log.P_ERR("----- Updated the GNSS XTRADATA FAILED ------") $ftpERRORs += 1 end return ret end #enable the XTRA function of quectel for faster GPS fix #this function is not running on current firmware of quectel def updateGPSFromFileSystem() #donwload xtra file system("curl -O http://xtrapath1.izatcloud.net/xtra.bin") #get utc time utctime= `curl -v --silent https://google.com/ 2>&1 \ | grep Date | sed -e 's/< Date: //' ` utctime=utctime.chomp.strip Log4Ienso.log.P_INFO("utctime is " + utctime) dt = `date -u -D'#{utctime}' +%Y/%m/%d,%T` #note in busbox the switch is -D, in ubuntu and others -d Log4Ienso.log.P_INFO(dt) Log4Ienso.log.P_INFO("enabling gps xtra mode") cmd = "at+qgpsxtra=1" Log4Ienso.log.P_INFO(cmd) r =sendATcmd(cmd) Log4Ienso.log.P_INFO(r) Log4Ienso.log.P_INFO("-------------------") fs =`ls -la xtra.bin | tr -s " " | cut -d " " -f5` fs=fs.chomp.strip Log4Ienso.log.P_INFO("uploading file to UFS") cmd = "AT+QFUPL='UFS:xtra.bin',"+fs+",90" Log4Ienso.log.P_INFO(cmd) r =sendATcmd(cmd) Log4Ienso.log.P_INFO(r) Log4Ienso.log.P_INFO("------------------------") sleep(90) Log4Ienso.log.P_INFO("injecting xtra time") cmd = "AT+QGPSXTRATIME=0,'#{dt}',1,1,5" Log4Ienso.log.P_INFO(cmd) r =sendATcmd(cmd) Log4Ienso.log.P_INFO(r) Log4Ienso.log.P_INFO("---------------------------") sleep(2) Log4Ienso.log.P_INFO("injecting file to GNSS") cmd = "AT+QGPSXTRADATA='UFS:xtra.bin'" Log4Ienso.log.P_INFO(cmd) r =sendATcmd(cmd) Log4Ienso.log.P_INFO(r) Log4Ienso.log.P_INFO("-------------------------") sleep(2) Log4Ienso.log.P_INFO("deleting file from UFS") cmd = "AT+QFDEL='UFS:xtra.bin'" Log4Ienso.log.P_INFO(cmd) r =sendATcmd(cmd) Log4Ienso.log.P_INFO(r) Log4Ienso.log.P_INFO("---------------------------") sleep(2) Log4Ienso.log.P_INFO("deleting xtra file") `rm xtra.bin` end def switchOnGPS() cmd = "AT+QGPS=1" r =sendATcmd(cmd) Log4Ienso.log.P_INFO(r) end def switchOffGPS() cmd = "AT+QGPSEND" r =sendATcmd(cmd) Log4Ienso.log.P_INFO(r) end def enableTZReporting count = 0 cmd ="at+ctzr=2" while count < 1 do Log4Ienso.log.P_INFO("cmd returned is " +cmd.to_s) r =sendATcmd(cmd) count+=1 if r == nil or r == "" or r == "ERROR" or r=="OK" next else break end end end def getFirmwareVersion cmd ="ati" count = 0 while count < 3 do Log4Ienso.log.P_INFO("cmd returned is " +cmd.to_s) r =sendATcmd(cmd) count+=1 if r == nil or r == "" or r == "ERROR" or r=="OK" next else break end end r=r.split(':') if r != nil r=r[1].strip if r[1] != nil return r end # this function will return either A for AT&T or V for verizon # this function must be called after determining the country of the sime card # in the case of usa country code is 310 or 311 def getUSANetwork(firmwareversion) f=nil begin if(firmwareversion == nil) return nil end f=firmwareversion[4].strip.chomp rescue Exception => e f=nil ensure return f end end def updateTZ count = 0 cmd ="at+ctzu=3" while count < 2 do Log4Ienso.log.P_INFO("cmd is " +cmd.to_s) r =sendATcmd(cmd) Log4Ienso.log.P_INFO("Status of ctzu is #{r}") count+=1 if r == nil or r == "" or r == "ERROR" or r=="OK" next else break end end end def fixSim `echo at+qmbncfg=\"select\",\"hVoLTE-Verizon\" > /dev/ttyUSB3` cmd ="at+qmbncfg=\"select\",\"hVoLTE-Verizon\"" sendATcmd(cmd) return "Rergistered sim card" end def getUpdatedQLTStime(qlts) rawdate = qlts.split("QLTS:") year=month=day=hour=0 len =0 if rawdate[1] != nil rawdate[1].gsub!(/\"|"\Z/, '' ) if( rawdate[1] == nil) return -1,-1,-1,-1 end len = rawdate[1].strip.chomp.length Log4Ienso.log.P_INFO( "the length of qlts is #{ len.to_s} ") end if len > 20 data = rawdate[1].split(",") ymd = data[0].split("/") year = ymd[0] month = ymd[1] day = ymd[2] Log4Ienso.log.P_INFO("QLTS year is #{year} | #{month}| #{day} << ") hrminsec = data[1].split(":") hour = hrminsec[0] return year,month,day,hour end return -1,-1,-1,-1 end def manageDST2019to2028 (year, month, today) begin m = month.to_i if (m != 3 or m != 11) and today > 15 Log4Ienso.log.P_INFO("month /day not in range for DST #{month} #{today}") return end if m>=1 and m<=9 month = "0"+m.to_s end h = Hash[ "2019-03"=>10, "2019-11"=>3, "2020-03"=>8, "2020-11"=>1, "2021-03"=>14, "2021-11"=>7, "2022-03"=>13, "2022-11"=>6, "2023-03"=>12, "2023-11"=>5, "2024-03"=>10, "2024-11"=>3, "2025-03"=>9, "2025-11"=>2, "2026-03"=>8, "2026-11"=>1, "2027-03"=>14, "2027-11"=>7, "2028-03"=>12, "2028-11"=>5, ] dt = year.to_s.strip+"-"+month.to_s.strip day = h[dt] if day.to_i == today.to_i $dstrebootflag = 1 #enable the flag to reboot on next wakeup Log4Ienso.log.P_INFO("reboot reqd for DST") else Log4Ienso.log.P_INFO("ignore dst logic for #{dt} and day #{day} #{today}") end rescue Exception=>e Log4Ienso.log.P_INFO("malformed input to DST function") end end #sets the locatime on A83 and returns the TZ value in hours def setLocalTime(mode=0) Log4Ienso.log.P_INFO("######################################################################") count = 0 while count < 3 do r = sendATcmd("at+cclk?") count+=1 if r == nil or r == "" or r == "ERROR" or r=="OK" next else break end end if r == nil or r=="" or r=="ERROR" or r=="OK" or r == nil or r == false Log4Ienso.log.P_INFO("returning from first check") Log4Ienso.log.P_INFO("######################################################################") return "" end reply = r rawdate = r.split("cclk:") Log4Ienso.log.P_INFO("the raw dat is " + rawdate.to_s) if rawdate[1] != nil rawdate[1].gsub!(/\"|"\Z/, '' ) if( rawdate[1] == nil) return "" end len = rawdate[1].strip.chomp.length Log4Ienso.log.P_INFO( "the length of rawdate is " + len.to_s ) if len == 17 Log4Ienso.log.P_ERR("#######################################") Log4Ienso.log.P_WARN("[LTE] cclk did not return TZ") Log4Ienso.log.P_ERR("#######################################") $tzERROR += 1 updateTZ enableTZReporting #return 0 end if len == 20 Log4Ienso.log.P_INFO("[LTE] cclk returned TZ") =begin #