package Ġnz . sc ut tle but t . t rem ola . ss b . pe ering Ċ Ċ import Ġandroid . util . Log Ċ import Ġnz . sc ut tle but t . t rem ola . ss b . T rem ola State Ċ import Ġkotlin . collections . ArrayList Ċ Ċ import Ġnz . sc ut tle but t . t rem ola . ss b . db . entities . LogEntry Ċ import Ġnz . sc ut tle but t . t rem ola . utils . Helper Functions . Companion . de Ref Ċ import Ġjava . util . concurrent . Executors Ċ import Ġjava . util . concurrent . locks . Re entrant Lock Ċ Ċ /** Ċ Ġ* ĠThe Ġlist Ġof Ġall Ġthe Ġknown Ġpeers , Ġboth Ġactive Ġand Ġknown Ġ( active Ġor Ġnot ) Ċ Ġ*/ Ċ class ĠPe ering Pool ( val Ġt rem ola State : ĠT rem ola State ) Ġ{ ĊĠĠĠ Ġval Ġactive Peers : ĠMutable List < Rpc Loop > Ġ= ĠArrayList () ĊĠĠĠ Ġprivate Ġval Ġknown Remote Front ier : ĠMutable Map < String , ĠMutable Map < String , ĠInt >> Ġ= Ġmutable Map Of () ĊĠĠĠ Ġprivate Ġval Ġl ck Ġ= ĠRe entrant Lock () ĊĊĠĠĠ Ġ// Ġ@ Suppress Lint (" Check Result ") ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠMake Ġcontact Ġwith Ġa Ġpeer Ġif Ġhe Ġis Ġin Ġthe Ġdatabase . ĊĠĠĠĠ Ġ* Ġ@ param Ġhost : Ġthe Ġremote ĠIP Ġaddress ĊĠĠĠĠ Ġ* Ġ@ param Ġport : Ġthe Ġremote ĠIP Ġport ĊĠĠĠĠ Ġ* Ġ@ param Ġremote F id : Ġthe Ġother Ġpeer 's Ġfeed Ġid , Ġi . e . Ġits Ġpublic Ġkey ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġadd ( host : ĠString , Ġport : ĠInt , Ġremote F id : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Ġonly Ġestablish Ġconnection Ġto Ġtrusted Ġdevices ĊĠĠĠĠĠĠĠ Ġif Ġ( t rem ola State . contact DAO . get Contact By L id ( remote F id ) Ġ== Ġnull ) Ġreturn ĊĠĠĠĠĠĠĠ Ġ// Ġonly Ġinitiate Ġif Ġnot Ġalready Ġconnected ĊĠĠĠĠĠĠĠ Ġfor Ġ( peer Ġin Ġactive Peers ) Ġif Ġ( peer . peer F id Ġ== Ġremote F id ) Ġreturn ĊĠĠĠĠĠĠĠ Ġval Ġremote Key Ġ= Ġremote F id . de Ref () Ġ// ĠBase 6 4 . decode ( remote F id . slice ( 1 .. remote F id . last Index - 8 ), ĠBase 6 4 . NO _ WRAP ) ĊĠĠĠĠĠĠĠ Ġval Ġrpc Stream Ġ= ĠRpc Init iator ( t rem ola State , Ġremote Key ) Ġ// Ġnull , ĠConstants . SS B _ NETWORK IDENTIFIER ) ĊĠĠĠĠĠĠĠ ĠaddTo Active ( rpc Stream ) ĊĠĠĠĠĠĠĠ Ġval Ġex Ġ= ĠExec utors . new Single Thread Executor () Ġ// Ġone Ġthread Ġper Ġpeer ĊĠĠĠĠĠĠĠ Ġex ?. execute Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrpc Stream . define Services ( Rpc Services ( t rem ola State )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrpc Stream . start Pe ering ( host , Ġport ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġremove From Active ( rpc Stream ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠBecause Ġpeer Ġmay Ġhave Ġlimited Ġthe Ġ# Ġof Ġentries Ġsent Ġto Ġus . ĊĠĠĠĠ Ġ* Ġ( see Ġhandle E BT msg ()) ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġkick () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcontacts Ġ= Ġt rem ola State . contact DAO . getAll () ĊĠĠĠĠĠĠĠ Ġfor Ġ( peer Ġin Ġactive Peers ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ("( Re -) trigger ĠE BT ", Ġ" for Ġ${ peer . peer F id }") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( contact Ġin Ġcontacts ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlatest Ġ= Ġt rem ola State . log DAO . get Most Recent Event From Log Id ( contact . lid ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠLog . d (" get Most Recent ", Ġ"${ lid } Ġat Ġ${ latest ?. lid }/${ latest ?. ls q }") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpeer . rpc Service ?. send E BT note ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpeer . rpc Service !!. eb t Rpc Nr , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontact . lid , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( latest Ġ== Ġnull ) Ġ 0 Ġelse Ġlatest . ls q ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ/* ĊĠĠĠĠĠĠĠ Ġfor Ġ( ongo ing Ġin Ġactive Peers ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġongoing . request Hist ories ( peers ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġnew LogEntry ( ev nt : ĠLog Entry ) Ġ{ ĊĠĠĠĠĠĠĠ ĠLog . d (" peers . propagate ", Ġ" do Ġit Ġfor Ġ${ active Peers . size } Ġactive Ġpeers ") ĊĠĠĠĠĠĠĠ Ġfor Ġ( peer Ġin Ġactive Peers ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d (" peers . propagate ", Ġ" consider Ġ${ peer . peer Mark } Ġ${ peer . rpc Service ?. eb t Rpc Nr }") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( peer . peer F id Ġin Ġknown Remote Front ier ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfmap Ġ= Ġknown Remote Front ier . get ( peer . peer F id ) !! ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d (" peers . propagate ", Ġ" found Ġmap Ġ${ f map }, Ġ${ ev nt . lid Ġin Ġfmap }") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( ev nt . lid Ġin Ġfmap Ġ&& Ġfmap . get ( ev nt . lid ) !! Ġ< Ġev nt . ls q ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( peer . rpc Service ?. eb t Rpc Nr Ġ!= Ġ 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpeer . rpc Service ?. send LogEntry ( peer . rpc Service !!. eb t Rpc Nr , Ġev nt , Ġfalse ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d (" peers . propagate ", Ġ"${ peer . peer F id } Ġno Ġneed : Ġ${ f map . get ( ev nt . lid )} Ġ/ Ġev nt . ls q =${ ev nt . ls q }") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d (" peers . propagate ", Ġ"${ peer . peer F id } Ġis Ġnot Ġin Ġknown Remote Front ier ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠAdd Ġa Ġnew Ġcontact . ĊĠĠĠĠ Ġ* Ġ@ param Ġfeed ID , Ġwhich Ġis Ġthe Ġpeer ĠS SB ĠID ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġnew Contact ( feed ID : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ ĠLog . d (" peers . contact ", Ġ" do Ġit Ġfor Ġ${ active Peers . size } Ġactive Ġpeers ") ĊĠĠĠĠĠĠĠ Ġfor Ġ( peer Ġin Ġactive Peers ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d (" peers . contact ", Ġ" consider Ġ${ peer . peer Mark } Ġ${ peer . rpc Service ?. eb t Rpc Nr }") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( peer . rpc Service ?. eb t Rpc Nr Ġ!= Ġ 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpeer . rpc Service ?. send E BT note ( peer . rpc Service !!. eb t Rpc Nr , Ġfeed ID , Ġ 0 ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġclose All () Ġ{ ĊĠĠĠĠĠĠĠ Ġfor Ġ( peer Ġin Ġactive Peers ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpeer . close () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠAdd Ġto Ġthe Ġlist Ġof Ġactive Ġpeers . ĊĠĠĠĠ Ġ* ĠIf Ġnot Ġin Ġthe Ġdatabase Ġyet , Ġadd Ġit Ġthere ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun ĠaddTo Active ( rpc : ĠRpc Loop ) Ġ{ ĊĠĠĠĠĠĠĠ Ġl ck . lock () ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġactive Peers . add ( rpc ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d (" addTo Active ", Ġ" added Ġ${ rpc . peer F id }, Ġnow Ġ${ active Peers . size } Ġentries ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( rpc . peer F id Ġ! in Ġknown Remote Front ier ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġknown Remote Front ier . put ( rpc . peer F id !! , Ġmutable Map Of ()) ĊĠĠĠĠĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġl ck . unlock () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġremove From Active ( rpc : ĠRpc Loop ) Ġ{ ĊĠĠĠĠĠĠĠ Ġl ck . lock () ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġactive Peers . remove ( rpc ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d (" addTo Active ", Ġ" removed , Ġnow Ġ${ active Peers . size } Ġentries , Ġ${ this }/${ active Peers }") ĊĠĠĠĠĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġl ck . unlock () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġupdate Known Front ier ( peer F id : ĠString , Ġfid : ĠString , Ġhighest : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠ Ġl ck . lock () ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(!( peer F id Ġin Ġknown Remote Front ier )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġknown Remote Front ier . put ( peer F id , Ġmutable Map Of ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġm Ġ= Ġknown Remote Front ier . get ( peer F id ) !! ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(!( fid Ġin Ġm ) Ġ|| Ġm . get ( fid ) !! Ġ< Ġhighest ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm . put ( fid , Ġhighest ) ĊĠĠĠĠĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġl ck . unlock () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } ĊĊĊĊ