// ĠCopyright Ġ 2 0 1 7 - 2 0 2 0 ĠFit bit , ĠInc Ċ // ĠSPDX - License - Identifier : ĠApache - 2 . 0 Ċ Ċ package Ġcom . fit bit . gold eng ate . node . stack Ċ Ċ import Ġandroid . annotation . Suppress Lint Ċ import Ġandroid . bluetooth . Bluetooth Device Ċ import Ġcom . fit bit . bluetooth . fb g att . Fit bit Gatt Ċ import Ġcom . fit bit . bluetooth . fb g att . Gatt Connection Ċ import Ġcom . fit bit . bluetooth . fb g att . rx . M tu Update Listener Ċ import Ġcom . fit bit . bluetooth . fb g att . rx . Per ipheral Connection ChangeListener Ċ import Ġcom . fit bit . bluetooth . fb g att . rx . Per ipheral Connection Status Ċ import Ġcom . fit bit . bluetooth . fb g att . rx . Per ipheral Dis connector Ċ import Ġcom . fit bit . bluetooth . fb g att . rx . client . Bit Gatt Peer Ċ import Ġcom . fit bit . gold eng ate . bindings . co ap . Co ap Group Request Filter Mode Ċ import Ġcom . fit bit . gold eng ate . bindings . dt ls . D tls Protocol Status Ċ import Ġcom . fit bit . gold eng ate . bindings . dt ls . D tls Protocol Status . Tls Protocol State . TLS _ STATE _ ERROR Ċ import Ġcom . fit bit . gold eng ate . bindings . dt ls . D tls Protocol Status . Tls Protocol State . TLS _ STATE _ SESSION Ċ import Ġcom . fit bit . gold eng ate . bindings . node . Bluetooth Address Node Key Ċ import Ġcom . fit bit . gold eng ate . bindings . stack . D tls Socket Net if Gatt link Ċ import Ġcom . fit bit . gold eng ate . bindings . stack . Stack Ċ import Ġcom . fit bit . gold eng ate . bindings . stack . Stack Config Ċ import Ġcom . fit bit . gold eng ate . bindings . stack . Stack Event Ċ import Ġcom . fit bit . gold eng ate . bindings . stack . Stack Service Ċ import Ġcom . fit bit . gold eng ate . bt . Peer Role Ċ import Ġcom . fit bit . gold eng ate . bt . Peer Connector Ċ import Ġcom . fit bit . gold eng ate . node . Bridge Ċ import Ġcom . fit bit . gold eng ate . node . Link up Ċ import Ġcom . fit bit . gold eng ate . node . Link up With Peer Node Handler Ċ import Ġcom . fit bit . gold eng ate . node . Link up Handler Provider Ċ import Ġcom . fit bit . gold eng ate . node . M tu Change Request er Ċ import Ġcom . fit bit . gold eng ate . node . Peer Ċ import Ġcom . fit bit . gold eng ate . node . Peer Connection Status Ċ import Ġcom . fit bit . gold eng ate . node . Stack EventHandler Ċ import Ġcom . fit bit . gold eng ate . per ipheral . Node Disconnected Exception Ċ import Ġio . reactivex . Comp letable Ċ import Ġio . reactivex . Observable Ċ import Ġio . reactivex . Single Ċ import Ġio . reactivex . dis pos ables . Disposable Ċ import Ġio . reactivex . functions . Bi Function Ċ import Ġio . reactivex . functions . Function Ċ import Ġio . reactivex . schedul ers . Schedulers Ċ import Ġio . reactivex . subjects . Publish Subject Ċ import Ġtim ber . log . Tim ber Ċ import Ġjava . util . concurrent . TimeUnit Ċ Ċ const Ġval ĠSTACK _ NODE _ DEFAULT _ MT U Ġ= Ġ 2 4 7 Ċ const Ġval ĠSTACK _ NODE _ CONNECTION _ TIMEOUT _ SECONDS : ĠLong Ġ= Ġ 6 0 Ċ Ċ /** Ċ Ġ* ĠA Ġ[ Peer ] Ġ( hub Ġor Ġnode ) Ġthat Ġencaps ulates Ġa Ġconnection Ġvia Ġa Ġ[ Stack ] Ġincluding Ġthe Ġ[ Stack Config ], Ċ Ġ* Ġ[ Stack Service ], Ġ[ Stack ], Ġand Ġ[ Bridge ] Ċ Ġ* Ċ Ġ* Ġ@ param Ġkey Ġthe Ġ[ Bluetooth Address Node Key ] Ġto Ġuse Ġfor Ġthis Ġ[ Stack Peer ] Ċ Ġ* Ġ@ param Ġstack Config Ġthe Ġ[ Stack Config ] Ġof Ġthe Ġ[ Stack ] Ċ Ġ* Ġ@ param Ġstack Service Ġthe Ġ[ Stack Service ] Ġat Ġthe Ġtop Ġof Ġthe Ġ[ Stack ] Ċ Ġ* Ġ@ param Ġlink up Handler Ġthe Ġ[ Link up With Peer Node Handler ] Ġused Ġto Ġlink Ġup Ġthe Ġstack Ġto Ġgold en Ġgate Ġstack Ġservices Ċ Ġ* Ġ@ param Ġpeer Connector Ġthe Ġ[ Peer Connector ] Ġused Ġto Ġconnect Ġthe Ġstack Ġto Ġthe Ġg att Ġlayer Ċ Ġ* Ġ@ param Ġconnection Status Provider Ġprovides Ġan ĠObservable Ġstream Ġwhich Ġemits Ġ[ Per ipheral Connection Status ] Ġupdates Ġwhen Ġprovided Ġa Ġ[ Gatt Connection ] Ċ Ġ* Ġ@ param Ġdt ls Event Observable Provider Ġprovides Ġan ĠObservable Ġstream Ġwhich Ġemits Ġ[ D tls Protocol Status ] Ġupdates Ġwhen Ġprovided Ġa Ġ[ Stack ] Ċ Ġ* Ġ@ param Ġpeer Provider Ġa Ġfunction Ġwhich Ġreturns Ġa Ġ[ Bit Gatt Peer ] Ġfor Ġa Ġgiven Ġ[ Gatt Connection ] Ċ Ġ* Ġ@ param Ġmt u Change Request er Provider Ġprovides Ġand Ġ[ M tu Change Request er ] Ġwhen Ġprovided Ġan Ġ[ Int ] Ġand Ġa Ġ[ Stack ] Ċ Ġ* Ġ@ param Ġstart M tu Ġthe Ġdefault Ġmt u Ġused Ġwhen Ġconnecting Ċ Ġ* Ġ@ param Ġconnect Timeout Ġtimeout Ġin Ġ[ TimeUnit . SECONDS ] Ġwhen Ġconnecting Ċ Ġ* Ġ@ param Ġbuild Stack Ġbuilds Ġa Ġ[ Stack ] Ġwhen Ġprovided Ġa Ġ[ Bridge ] Ċ Ġ* Ġ@ param Ġbuild Bridge Ġbuilds Ġa Ġ[ Bridge ] Ġwhen Ġprovided Ġa Ġ[ Bluetooth Device ] Ċ Ġ* Ġ@ param Ġmt u Request Subject Ġused Ġto Ġinform Ġan Ġactive Ġconnection Ġof Ġa Ġdesired Ġmt u Ċ Ġ* Ġ@ param Ġstack Event Observable Provider Ġprovides Ġan ĠObservable Ġstream Ġwhich Ġemits Ġ[ Stack Event ] Ġupdates Ġwhen Ġprovided Ġa Ġ[ Stack ] Ċ Ġ* Ġ@ param Ġstack EventHandler Provider Ġprovides Ġa Ġ[ Stack Event ] Ġdispatcher Ġfor Ġa Ġgiven Ġ[ Stack ] Ġand Ġ[ Gatt Connection ] Ċ Ġ*/ Ċ class ĠStack Peer < T : ĠStack Service > Ġinternal Ġconstructor ( ĊĠĠĠ Ġval Ġkey : ĠBluetooth Address Node Key , ĊĠĠĠ Ġpeer Role : ĠPeer Role , ĊĠĠĠ Ġval Ġstack Config : ĠStack Config , ĊĠĠĠ Ġstack Service : ĠT , ĊĠĠĠ Ġprivate Ġval Ġlink up Handler : ĠLink up Ġ= ĠLink up Handler Provider . get Handler ( peer Role ), ĊĠĠĠ Ġprivate Ġval Ġpeer Connector : ĠPeer Connector Ġ= ĠPeer Connector ( key . value , Ġpeer Role ), ĊĠĠĠ Ġprivate Ġval Ġconnection Status Provider : Ġ( Gatt Connection ) Ġ-> ĠObservable < Per ipheral Connection Status > Ġ= Ġ{ ĠPer ipheral Connection ChangeListener (). register ( it ) Ġ}, ĊĠĠĠ Ġprivate Ġval Ġdt ls Event Observable Provider : Ġ( stack : ĠStack ) Ġ-> ĠObservable < D tls Protocol Status > Ġ= Ġ{ Ġit . dt ls Event Observable Ġ}, ĊĠĠĠ Ġprivate Ġval Ġpeer Provider : Ġ( g att Connection : ĠG att Connection ) Ġ-> ĠBit Gatt Peer Ġ= Ġ{ Ġg att Connection Ġ-> ĠBit Gatt Peer ( g att Connection ) Ġ}, ĊĠĠĠ Ġprivate Ġval Ġmt u Change Request er Provider : Ġ( Stack ) Ġ-> ĠM tu Change Request er Ġ= Ġ{ Ġstack Ġ-> ĠM tu Change Request er ( key . value , Ġstack ) Ġ}, ĊĠĠĠ Ġprivate Ġval Ġstart M tu : ĠInt Ġ= ĠSTACK _ NODE _ DEFAULT _ MT U , ĊĠĠĠ Ġprivate Ġval Ġconnect Timeout : ĠLong Ġ= ĠSTACK _ NODE _ CONNECTION _ TIMEOUT _ SECONDS , ĊĠĠĠ Ġprivate Ġval Ġbuild Stack : Ġ( Bridge ) Ġ-> ĠStack Ġ= Ġ{ ĊĠĠĠĠĠĠĠ ĠStack ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġkey , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġit . getAs Data Sink Pointer (), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġit . getAs DataSource Pointer (), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstack Config , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis Node Ġ= Ġ( peer Role Ġ== ĠPeer Role . Central ) ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ}, ĊĠĠĠ Ġprivate Ġval Ġbuild Bridge : Ġ( Gatt Connection ) Ġ-> ĠBridge Ġ= Ġ{ ĠBridge ( it ) Ġ}, ĊĠĠĠ Ġprivate Ġval Ġmt u Update Listener Provider : Ġ( Gatt Connection ) Ġ-> ĠObservable < Int > Ġ= Ġ{ ĠM tu Update Listener (). register ( it ) Ġ}, ĊĠĠĠ Ġprivate Ġval Ġstack EventHandler Provider : Ġ( Observable < Stack Event >, ĠG att Connection ) Ġ-> ĠStack EventHandler Ġ= Ġ{ Ġobs , Ġconn Ġ-> ĠStack EventHandler ( obs , Ġconn ) Ġ}, ĊĠĠĠ Ġprivate Ġval Ġstack Event Observable Provider : Ġ( Stack ) Ġ-> ĠObservable < Stack Event > Ġ= Ġ{ Ġit . stack Event Observable Ġ}, ĊĠĠĠ Ġfit bit Gatt : ĠFit bit Gatt Ġ= ĠFit bit Gatt . getInstance (), ĊĠĠĠ Ġprivate Ġval Ġperipheral Dis connector : ĠPer ipheral Dis connector Ġ= ĠPer ipheral Dis connector ( fit bit Gatt ) Ċ ): ĠPeer < T >( stack Service , Ġpeer Role ) Ġ{ ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠUtility Ġconstructor Ġfor Ġinject ing Ġ[ connection Status Provider ] Ġand Ġ[ dt ls Event Observable Provider ] ĊĠĠĠĠ Ġ* Ġused Ġfor Ġstatus Ġmessages Ġin Ġthe ĠHost Ġapp ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġconstructor ( ĊĠĠĠĠĠĠĠ Ġkey : ĠBluetooth Address Node Key , ĊĠĠĠĠĠĠĠ Ġpeer Role : ĠPeer Role , ĊĠĠĠĠĠĠĠ Ġstack Config : ĠStack Config , ĊĠĠĠĠĠĠĠ Ġstack Service : ĠT , ĊĠĠĠĠĠĠĠ Ġconnection Status Provider : Ġ( Gatt Connection ) Ġ-> ĠObservable < Per ipheral Connection Status >, ĊĠĠĠĠĠĠĠ Ġdt ls Event Observable Provider : Ġ( stack : ĠStack ) Ġ-> ĠObservable < D tls Protocol Status > ĊĠĠĠ Ġ): Ġthis ( ĊĠĠĠĠĠĠĠ Ġkey , ĊĠĠĠĠĠĠĠ Ġpeer Role , ĊĠĠĠĠĠĠĠ Ġstack Config , ĊĠĠĠĠĠĠĠ Ġstack Service , ĊĠĠĠĠĠĠĠ ĠLink up Handler Provider . get Handler ( peer Role ), ĊĠĠĠĠĠĠĠ ĠPeer Connector ( key . value , Ġpeer Role ), ĊĠĠĠĠĠĠĠ Ġconnection Status Provider , ĊĠĠĠĠĠĠĠ Ġdt ls Event Observable Provider ĊĠĠĠ Ġ) ĊĊĠĠĠ Ġprivate Ġvar Ġpeer Connection Observable : ĠObservable < Peer Connection Status >? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġdis posable : ĠDis posable ? Ġ= Ġnull ĊĊĠĠĠ Ġ@ Synchron ized ĊĠĠĠ Ġoverride Ġfun Ġconnection (): ĠObservable < Peer Connection Status > Ġ= ĊĠĠĠĠĠĠĠ Ġpeer Connection Observable ?. also Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . i (" Stack Peer Ġwith Ġkey Ġ$ key Ġhas Ġa Ġconnection ") ĊĠĠĠĠĠĠĠ Ġ} ?: Ġconnect (). also Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . i (" Stack Peer Ġwith Ġkey Ġ$ key Ġdoes Ġnot Ġhave Ġa Ġconnection ") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Synchron ized ĊĠĠĠ Ġoverride Ġfun Ġdisconnect () Ġ{ ĊĠĠĠĠĠĠĠ ĠTim ber . i (" Stack Peer Ġwith Ġkey Ġ$ key Ġconnection Ġis Ġdisconnect ing ") ĊĠĠĠĠĠĠĠ Ġdis posable ?. dispose () ĊĠĠĠĠĠĠĠ Ġdisconnect Per ipheral () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġconnect (): ĠObservable < Peer Connection Status > Ġ{ ĊĠĠĠĠĠĠĠ ĠTim ber . i (" Stack Peer Ġwith Ġkey Ġ$ key Ġconnection Ġis Ġcreating Ġa Ġnew Ġconnection ") ĊĠĠĠĠĠĠĠ Ġ// Create Ġan Ġobservable Ġthat Ġcan Ġcomplete Ġwhen Ġdisposed . ĠAllows Ġdisconnect Ġto Ġtrigger ĠonComplete ĊĠĠĠĠĠĠĠ Ġreturn ĠObservable . create < Peer Connection Status > Ġ{ Ġemitter Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . i (" Stack Peer Ġwith Ġkey Ġ$ key Ġconnection Ġis Ġstarting Ġthe Ġconnection ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// 1 . ĠConnect Ġthe Ġdevice ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpeer Connector . connect (). flatMap Observable Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// 2 . ĠBuild Ġthe Ġstack , Ġbridge , Ġand Ġattach Ġthe Ġservice ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsetup Stack ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}. flatMap Ġ{ Ġstate Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . i (" Stack Peer Ġwith Ġkey Ġ$ key Ġmt u Changed Handler Ġ$ state ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// 3 . Ġsubscribe Ġto ĠMT U Ġupdate Ġobservable ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmt u Update Handler ( state ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. start With ( Observable . just ( state )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}. flatMap Single Ġ{ Ġstate Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// 4 . ĠSend ĠMT U Ġupdate Ġrequest ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( peer Role Ġ== ĠPeer Role . Per ipheral ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmt u Change Request er Provider ( state . stack ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. request M tu ( state . peer , Ġstart M tu ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġstate Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠSingle . just ( state ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}. flatMap Single Ġ{ Ġstate Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// 5 . Ġstart Ġlink - up Ġprocedure ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . i (" Stack Peer Ġwith Ġkey Ġ$ key Ġstart Ġlink Ġup Ġhandler ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlink up Handler . link ( state . peer ). and Then ( Single . just ( state )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}. flatMap Ġ{ Ġstate Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// 6 . ĠStart Ġstack ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . i (" Stack Peer Ġwith Ġkey Ġ$ key Ġstarting Ġstack Ġand Ġbridge ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstate . bridge . start () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstate . stack . start () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// 7 . ĠWait Ġfor Ġconnected Ġevents ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠwaitFor Connected State ( state ). map Ġ{ Ġstate Ġto Ġit Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}. flatMap Ġ{ Ġ( state , Ġstatus ) Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// 8 . ĠListen Ġto Ġstack Ġevents Ġand Ġreact Ġto Ġit ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlisten To Stack Events ( state ). start With ( Observable . just ( status )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}. do On Dispose Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . i (" Stack Peer Ġwith Ġkey Ġ$ key Ġconnection Ġis Ġbeing Ġdisposed .") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġemitter . onComplete () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}. do Finally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġremove Active Connection () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}. subscribe ({ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . i (" Stack Peer Ġwith Ġkey Ġ$ key Ġconnection Ġhas Ġupdated Ġits Ġstatus Ġto Ġ$ it ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġemitter . onNext ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}, Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . e ( it , Ġ" Stack Peer Ġwith Ġkey Ġ$ key Ġconnection Ġhas Ġthrown Ġan Ġerror ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġemitter . onError ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}). also Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . i (" Stack Peer Ġwith Ġkey Ġ$ key Ġconnection Ġis Ġsaving Ġa Ġreference Ġto Ġits Ġdis posable Ġto Ġdisconnect Ġlater ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdis posable Ġ= Ġit ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ// Use Ġthe Ġconnection Ġto Ġa Ġsingle Ġobservable Ġfor Ġany Ġfuture Ġsubscriptions Ġto Ġavoid Ġrace Ġconditions ĊĠĠĠĠĠĠĠ Ġ. replay () ĊĠĠĠĠĠĠĠ Ġ. auto Connect () ĊĠĠĠĠĠĠĠ Ġ. also Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . i (" Stack Peer Ġwith Ġkey Ġ$ key Ġconnection Ġis Ġsaving Ġa Ġreference Ġto Ġits Ġobservable Ġshare Ġlater ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpeer Connection Observable Ġ= Ġit ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġsetup Stack ( connection : ĠG att Connection ): ĠObservable < Connection State > Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĠObservable . create < Connection State > Ġ{ Ġstack Emitter Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsynchronized ( this @ Stack Peer ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . i (" Stack Peer Ġwith Ġkey Ġ$ key Ġbuilding Ġstack Ġand Ġbridge Ġand Ġis Ġatt aching Ġit Ġto Ġthe Ġservice ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbridge Ġ= Ġbuild Bridge ( connection ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstack Ġ= Ġbuild Stack ( bridge ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstack Service . attach ( stack ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpeer Ġ= Ġpeer Provider ( connection ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġconnection State Ġ= ĠConnection State ( bridge , Ġstack , Ġpeer , Ġconnection ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstack Emitter . set C ancellable Ġ{ ĠtearDown ( connection State ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġconnection State ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}. let Ġ{ Ġstack Emitter . onNext ( it ) Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠPerform ĠMT U Ġchange Ġfor ĠStack Ġonly Ġwhen ĠBT Ġconnection ĠMT U Ġchanges . ĠConnection ĠMT U Ġcan Ġbe ĊĠĠĠĠ Ġ* Ġchanged Ġby Ġconnected Ġpeer Ġin Ġwhich Ġcase Ġwe Ġneed Ġto Ġupdate Ġthe Ġstack ĠMT U ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġmt u Update Handler ( connection State : ĠConnection State ): ĠComp letable Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĠObservable . defer Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmt u Update Listener Provider ( connection State . g att Connection ) ĊĠĠĠĠĠĠĠ Ġ}. flatMap Single Ġ{ Ġmt u Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . d (" received Ġnew Ġmt u : Ġ$ mt u ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmt u Change Request er Provider ( connection State . stack ). update Stack M tu ( mt u ) ĊĠĠĠĠĠĠĠ Ġ}. ignore Elements () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġlisten To Stack Events ( connection State : ĠConnection State ): ĠComp letable Ġ= ĊĠĠĠĠĠĠĠ Ġstack EventHandler Provider ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstack Event Observable Provider ( connection State . stack ), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġconnection State . g att Connection ĊĠĠĠĠĠĠĠ Ġ). dispatch Events () ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠEmit s Ġ[ Peer Connection Status . CONNECTED ] Ġwhen Ġany Ġrelevant Ġevent Ġstreams Ġall Ġemit ĊĠĠĠĠ Ġ* Ġ[ Peer Connection Status . CONNECTED ]. ĠOnly Ġ[ Peer Connection Status . CONNECTED ] Ġis Ġthe Ġonly Ġvalue ĊĠĠĠĠ Ġ* Ġemitted Ġfrom Ġany Ġstream ; Ġso Ġwhen Ġall Ġemit Ġa Ġsingle Ġvalue Ġthen Ġit Ġwill Ġbe Ġconnected . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun ĠwaitFor Connected State ( connection State : ĠConnection State ): ĠObservable < Peer Connection Status > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġconnection Status Observable Ġ= Ġget Connection Status Observable ( connection State ) ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( stack Config Ġis ĠD tls Socket Net if Gatt link ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Gatt link Ġand Ġtls Ġevents Ġcombined ĊĠĠĠĠĠĠĠĠĠĠĠ ĠObservable . zip ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġconnection Status Observable , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġget D tls Event Observable ( connection State ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠBi Function Ġ{ Ġ_, Ġ_ Ġ-> ĠPeer Connection Status . CONNECTED Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Just ĠG att link Ġevents ĊĠĠĠĠĠĠĠĠĠĠĠ Ġconnection Status Observable ĊĠĠĠĠĠĠĠ Ġ}. timeout ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠTimeout Ġfor Ġfirst Ġemission Ġonly ĊĠĠĠĠĠĠĠĠĠĠĠ ĠObservable . empty < Peer Connection Status >(). delay ( connect Timeout , ĠTimeUnit . SECONDS ), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠFunction Ġ{ Ġ_: ĠPeer Connection Status Ġ-> ĠObservable . never < Any >() Ġ} ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠOnly Ġemits Ġ[ Peer Connection Status . CONNECTED ] Ġon Ġ[ TLS _ STATE _ SESSION ] Ġand Ġa ĊĠĠĠĠ Ġ* Ġ[ Node Disconnected Exception ] Ġif Ġthere Ġwas Ġa Ġ[ TLS _ STATE _ ERROR ] ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġget D tls Event Observable ( connection State : ĠConnection State ): ĠObservable < Peer Connection Status > Ġ= ĊĠĠĠĠĠĠĠ ĠObservable . defer Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . i (" Stack Peer Ġwith Ġkey Ġ$ key Ġlistening Ġto Ġtls Ġevents ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdt ls Event Observable Provider ( connection State . stack ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. do On Next Ġ{ ĠTim ber . d (" Stack Peer Ġwith Ġkey Ġ$ key ĠT ls Ġstatus Ġchanged Ġto Ġ${ it . state }") Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġtls Status Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ/* ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĠOnly Ġreact Ġto ĠTLS _ STATE _ SESSION , Ġexclude Ġall Ġother Ġstates Ġas Ġthey ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġdon 't Ġmatter Ġwhen Ġemit ting Ġa Ġtrue Ġconnection Ġand Ġthere Ġare ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġretries Ġbuild Ġin ĠXP Ġlibrary Ġfor ĠTLS _ STATE _ ERROR Ġstate ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtls Status . state Ġ== ĠTLS _ STATE _ SESSION ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}. map Ġ{ Ġtls Status Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen ( tls Status . state ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTLS _ STATE _ SESSION Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ/* ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĠIf ĠD TLS Ġconnection Ġis Ġnot Ġusing Ġthe Ġpublic Ġkeys , Ġupdate Ġthe Ġfilter Ġgroup . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( tls Status . ps k Identity Ġ!= Ġ" BOOT STR AP " Ġ&& ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtls Status . ps k Identity Ġ!= Ġ" hello ") Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstack Service . set Filter Group ( Co ap Group Request Filter Mode . GROUP _ 0 , Ġkey ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠPeer Connection Status . CONNECTED ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// This Ġwill Ġnever Ġhappen ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġthrow ĠIllegalStateException () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠOnly Ġemits Ġ[ Peer Connection Status . CONNECTED ] Ġon Ġ[ Per ipheral Connection Status . CONNECTED ] Ġand ĊĠĠĠĠ Ġ* Ġ[ Node Disconnected Exception ] Ġif Ġthere Ġwas Ġa Ġ[ Per ipheral Connection Status . DIS CONNECTED ] ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġget Connection Status Observable ( connection State : ĠConnection State ): ĠObservable < Peer Connection Status > Ġ= ĊĠĠĠĠĠĠĠ ĠObservable . defer Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . i (" Stack Peer Ġwith Ġkey Ġ$ key Ġlistening Ġto Ġperipheral Ġevents ") ĊĠĠĠĠĠĠĠĠĠĠĠ ĠObservable . just ( Per ipheral Connection Status . CONNECTED ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġconnection State . g att Connection . isConnected Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. concat With ( connection Status Provider ( connection State . g att Connection )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġstatus Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . i (" Stack Peer Ġwith Ġkey Ġ$ key Ġreceived Ġconnection Ġchange Ġstatus : Ġ$ status ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( status ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠPer ipheral Connection Status . CONNECTED Ġ-> ĠPeer Connection Status . CONNECTED ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠPer ipheral Connection Status . DIS CONNECTED Ġ-> Ġthrow ĠNode Disconnected Exception () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Synchron ized ĊĠĠĠ Ġprivate Ġfun Ġremove Active Connection () Ġ{ ĊĠĠĠĠĠĠĠ ĠTim ber . i (" Stack Peer Ġwith Ġkey Ġ$ key Ġis Ġremoving Ġthe Ġactive Ġconnection ") ĊĠĠĠĠĠĠĠ Ġdis posable Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġpeer Connection Observable Ġ= Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Synchron ized ĊĠĠĠ Ġprivate Ġfun ĠtearDown ( connection State : ĠConnection State ) Ġ{ ĊĠĠĠĠĠĠĠ ĠTim ber . i (" Stack Peer Ġwith Ġkey Ġ$ key Ġis Ġdet aching Ġits Ġservice Ġand Ġtear ing Ġdown Ġits Ġstack , Ġbridge ") ĊĠĠĠĠĠĠĠ Ġconnection State . bridge . suspend () ĊĠĠĠĠĠĠĠ Ġstack Service . detach () ĊĠĠĠĠĠĠĠ Ġstack Service . set Filter Group ( Co ap Group Request Filter Mode . GROUP _ 1 , Ġkey ) ĊĠĠĠĠĠĠĠ Ġconnection State . stack . close () ĊĠĠĠĠĠĠĠ Ġconnection State . bridge . close () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Suppress Lint (" Check Result ") ĊĠĠĠ Ġprivate Ġfun Ġdisconnect Per ipheral () Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠThis Ġis Ġa Ġfire - and - forget Ġcall ĊĠĠĠĠĠĠĠ Ġperipheral Dis connector . disconnect ( key . value ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. do On Subscribe Ġ{ ĠTim ber . d (" Disconnect ing Ġfrom Ġperipheral Ġ$ key ") Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. subscribe On ( Schedulers . io ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. subscribe ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ{ ĠTim ber . d (" We Ġdisconnected Ġfrom Ġthe Ġdevice ") Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ{ ĠTim ber . w ( it , Ġ" Error Ġdisconnect ing Ġfrom Ġdevice ") Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġdata Ġclass ĠConnection State ( val Ġbridge : ĠBridge , Ġval Ġstack : ĠStack , Ġval Ġpeer : ĠBit Gatt Peer , Ġval Ġg att Connection : ĠG att Connection ) Ċ } Ċ