package Ġorg . t cn co al ition . t cn client . bluetooth Ċ Ċ import Ġandroid . bluetooth . Bluetooth Device Ċ import Ġandroid . bluetooth . Bluetooth Gatt Ċ import Ġandroid . bluetooth . Bluetooth GattCharacteristic Ċ import Ġandroid . bluetooth . Bluetooth Gatt Server Ċ import Ġandroid . bluetooth . Bluetooth Gatt Server Callback Ċ import Ġandroid . bluetooth . Bluetooth Gatt Service Ċ import Ġandroid . bluetooth . Bluetooth Manager Ċ import Ġandroid . bluetooth . le . Ad vertise Callback Ċ import Ġandroid . bluetooth . le . Ad vertise Data Ċ import Ġandroid . bluetooth . le . Ad vertise Settings Ċ import Ġandroid . bluetooth . le . Bluetooth Le Ad vert iser Ċ import Ġandroid . bluetooth . le . Bluetooth Le Scanner Ċ import Ġandroid . bluetooth . le . Scan Callback Ċ import Ġandroid . bluetooth . le . Scan Filter Ċ import Ġandroid . bluetooth . le . Scan Result Ċ import Ġandroid . bluetooth . le . Scan Settings Ċ import Ġandroid . content . Context Ċ import Ġandroid . os . Build Ċ import Ġandroid . os . Handler Ċ import Ġandroid . os . Parcel Uuid Ċ import Ġandroid . util . Base 6 4 Ċ import Ġandroid . util . Log Ċ import Ġorg . t cn co al ition . t cn client . T cn Constants Ċ import Ġjava . util . Timer Ċ import Ġjava . util . Timer Task Ċ import Ġjava . util . UUID Ċ import Ġjava . util . concurrent . ExecutorService Ċ import Ġjava . util . concurrent . Executors Ċ import Ġjava . util . concurrent . TimeUnit Ċ Ċ class ĠT cn Bluetooth Manager ( ĊĠĠĠ Ġprivate Ġval Ġcontext : ĠContext , ĊĠĠĠ Ġprivate Ġval Ġscanner : ĠBluetooth Le Scanner , ĊĠĠĠ Ġprivate Ġval Ġadvert iser : ĠBluetooth Le Ad vert iser , ĊĠĠĠ Ġprivate Ġval Ġt cn Callback : ĠT cn Bluetooth Service Callback Ċ ) Ġ{ ĊĊĠĠĠ Ġprivate Ġvar Ġbluetooth Gatt Server : ĠBluetooth Gatt Server ? Ġ= Ġnull ĊĊĠĠĠ Ġprivate Ġvar Ġis Started : ĠBoolean Ġ= Ġfalse ĊĠĠĠ Ġprivate Ġvar Ġgenerated T cn Ġ= ĠByteArray ( 0 ) ĊĠĠĠ Ġprivate Ġvar Ġt cn Ad vertising Queue Ġ= ĠArrayList < ByteArray >() ĊĠĠĠ Ġprivate Ġvar Ġin Range B le Address To T cn Map Ġ= Ġmutable Map Of < String , ĠByteArray >() ĊĠĠĠ Ġprivate Ġvar Ġestimated Distance To Remote Device Address Map Ġ= Ġmutable Map Of < String , ĠDouble >() ĊĊĠĠĠ Ġprivate Ġvar Ġhandler Ġ= ĠHandler () ĊĠĠĠ Ġprivate Ġvar Ġad vertise Next T cn Timer : ĠTimer ? Ġ= Ġnull ĊĊĠĠĠ Ġprivate Ġvar Ġexecutor : ĠExecutor Service ? Ġ= Ġnull ĊĊĠĠĠ Ġfun Ġstart () Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( is Started ) Ġreturn ĊĠĠĠĠĠĠĠ Ġis Started Ġ= Ġtrue ĊĊĠĠĠĠĠĠĠ Ġstart Scan () ĊĠĠĠĠĠĠĠ Ġ// ĠCreate Ġthe Ġlocal ĠG ATT Server Ġand Ġopen Ġit Ġonce . ĊĠĠĠĠĠĠĠ Ġinit B le Gatt Server ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ( context . getSystem Service ( Context . BL U ETO OTH _ SERVICE ) Ġas ĠBluetooth Manager ), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠT cn Constants . UUID _ SERVICE ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġexecutor Ġ= ĠExec utors . new Fixed ThreadPool ( 2 ) ĊĠĠĠĠĠĠĠ Ġchange Own T cn () Ġ// ĠThis Ġstarts Ġadvertising Ġalso ĊĠĠĠĠĠĠĠ Ġrun Ad vertise Next T cn Timer () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġstop () Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! is Started ) Ġreturn ĊĠĠĠĠĠĠĠ Ġis Started Ġ= Ġfalse ĊĊĠĠĠĠĠĠĠ Ġstop Scan () ĊĠĠĠĠĠĠĠ Ġstop Ad vertising () ĊĠĠĠĠĠĠĠ Ġbluetooth Gatt Server ?. clear Services () ĊĠĠĠĠĠĠĠ Ġbluetooth Gatt Server ?. close () ĊĠĠĠĠĠĠĠ Ġbluetooth Gatt Server Ġ= Ġnull ĊĊĠĠĠĠĠĠĠ Ġhandler . remove Callbacks And Messages ( null ) ĊĠĠĠĠĠĠĠ Ġad vertise Next T cn Timer ?. cancel () ĊĠĠĠĠĠĠĠ Ġad vertise Next T cn Timer Ġ= Ġnull ĊĊĠĠĠĠĠĠĠ Ġt cn Ad vertising Queue . clear () ĊĠĠĠĠĠĠĠ Ġin Range B le Address To T cn Map . clear () ĊĠĠĠĠĠĠĠ Ġestimated Distance To Remote Device Address Map . clear () ĊĊĠĠĠĠĠĠĠ Ġexecutor ?. shutdown () ĊĠĠĠĠĠĠĠ Ġexecutor Ġ= Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġrun Ad vertise Next T cn Timer () Ġ{ ĊĠĠĠĠĠĠĠ Ġad vertise Next T cn Timer ?. cancel () ĊĠĠĠĠĠĠĠ Ġad vertise Next T cn Timer Ġ= ĠTimer () ĊĠĠĠĠĠĠĠ Ġad vertise Next T cn Timer ?. schedule At Fixed Rate ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġobject Ġ: ĠTimer Task () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġrun () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( t cn Ad vertising Queue . isEmpty ()) Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfirst TC N Ġ= Ġt cn Ad vertising Queue . first () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġt cn Ad vertising Queue . remove At ( 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġt cn Ad vertising Queue . add ( first TC N ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstop Ad vertising () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstart Ad vertising () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTimeUnit . SECONDS . to Millis ( 2 0 ), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTimeUnit . SECONDS . to Millis ( 2 0 ) ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġchange Own T cn () Ġ{ ĊĠĠĠĠĠĠĠ Ġexecutor ?. execute Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . i ( TAG , Ġ" Changing Ġown ĠT CN Ġ... ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠRemove Ġcurrent ĠT CN Ġfrom Ġthe Ġadvertising Ġqueue . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġde queue From Ad vertising ( generated T cn ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġt cn Ġ= Ġt cn Callback . generate T cn () ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . i ( TAG , Ġ" Did Ġgenerate ĠT CN =${ Base 6 4 . encode ToString ( t cn , ĠBase 6 4 . NO _ WRAP )} ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġgenerated T cn Ġ= Ġt cn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠEn queue Ġnew ĠT CN Ġto Ġthe Ġhead Ġof Ġthe Ġadvertising Ġqueue Ġso Ġit Ġwill Ġbe Ġadvert ised Ġnext . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġenqueue For Ad vertising ( t cn , Ġtrue ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠForce Ġrestart Ġadvertising Ġwith Ġnew ĠT CN ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstop Ad vertising () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstart Ad vertising () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġde queue From Ad vertising ( t cn : ĠByteArray ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġt cn Ġ?: Ġreturn ĊĠĠĠĠĠĠĠ Ġt cn Ad vertising Queue . remove ( t cn ) ĊĠĠĠĠĠĠĠ ĠLog . i ( TAG , Ġ" De queued ĠT CN =${ Base 6 4 . encode ToString ( t cn , ĠBase 6 4 . NO _ WRAP )} Ġfrom Ġadvertising ") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġenqueue For Ad vertising ( t cn : ĠByteArray ?, Ġat Head : ĠBoolean Ġ= Ġfalse ) Ġ{ ĊĠĠĠĠĠĠĠ Ġt cn Ġ?: Ġreturn ĊĠĠĠĠĠĠĠ Ġif Ġ( at Head ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġt cn Ad vertising Queue . add ( 0 , Ġt cn ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġt cn Ad vertising Queue . add ( t cn ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ ĠLog . i ( TAG , Ġ" En queued ĠT CN =${ Base 6 4 . encode ToString ( t cn , ĠBase 6 4 . NO _ WRAP )} Ġfor Ġadvertising ") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġstart Scan () Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! is Started ) Ġreturn ĊĠĠĠĠĠĠĠ Ġ// ĠUse Ġtry Ġcatch Ġto Ġhandle ĠDead Object Ġexception ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThe Ġuse Ġof Ġscan Ġfilters Ġaren 't Ġrequired Ġwhile Ġthe Ġapp Ġis Ġin Ġthe Ġforeground . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThis Ġchanges Ġwhen Ġthe Ġapp Ġis Ġin Ġthe Ġbackground . ĠIf Ġthey Ġare Ġmissing Ġthen Ġthe ĠBluetooth ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġframework Ġwon 't Ġgive Ġus Ġscan Ġresults . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġscan Filters Ġ= ĠarrayOf ( T cn Constants . UUID _ SERVICE ). map Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠScan Filter . Builder (). set Service Uuid ( Parcel Uuid ( it )). build () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġscan Settings Ġ= ĠScan Settings . Builder (). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠLow Ġlatency Ġis Ġimportant Ġfor Ġolder ĠAndroid Ġdevices Ġto Ġbe Ġable Ġto Ġdiscover Ġnearby ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġdevices . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġset Scan Mode ( Scan Settings . SCAN _ MODE _ LOW _ LAT ENCY ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġset Callback Type ( Scan Settings . CALLBACK _ TYPE _ ALL _ MATCH ES ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġset Match Mode ( Scan Settings . MATCH _ MODE _ AGG RESS IVE ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġset Num Of Matches ( Scan Settings . MATCH _ NUM _ MAX _ AD VER TI SE MENT ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠReport Ġdelay Ġplays Ġan Ġimportant Ġrole Ġin Ġkeeping Ġtrack Ġof Ġthe Ġdevices Ġnearby : ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠIf Ġa Ġbatch Ġscan Ġresult Ġdoesn 't Ġinclude Ġdevices Ġfrom Ġthe Ġprevious Ġresult , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġthen Ġwe Ġconsider Ġthose Ġdevices Ġout Ġof Ġrange . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠImport ant : ĠUsing Ġa Ġlarge Ġduration Ġvalue Ġ( greater Ġthan Ġ 6 0 Ġsec ) Ġwon 't Ġget Ġus Ġscan ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġresults Ġon Ġold ĠOS es ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġset Report Delay ( TimeUnit . SECONDS . to Millis ( 5 )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( Build . VERSION . SDK _ INT Ġ>= ĠBuild . VERSION _ CODES . O ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġset Phy ( Scan Settings . PHY _ LE _ ALL _ SUPPORTED ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġset Legacy ( true ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}. build () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġscanner . start Scan ( scan Filters , Ġscan Settings , Ġscan Callback ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . i ( TAG , Ġ" Started Ġscan ") ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( exception : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . e ( TAG , Ġ" Start Ġscan Ġfailed : Ġ$ exception ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstart Scan () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠBug Ġworkaround : ĠRestart Ġperiodically Ġso Ġthe ĠBluetooth Ġdaemon Ġwon 't Ġget Ġinto Ġa Ġbroken ĊĠĠĠĠĠĠĠ Ġ// Ġstate Ġon Ġold ĠAndroid Ġdevices . ĊĠĠĠĠĠĠĠ Ġhandler . remove Callbacks And Messages ( null ) ĊĠĠĠĠĠĠĠ Ġhandler . post Delayed ({ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( is Started ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . i ( TAG , Ġ" Re starting Ġscan ...") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠIf Ġthere Ġare Ġoutstanding Ġscan Ġresults Ġthen Ġflush Ġthem Ġso Ġwe Ġcan Ġprocess Ġthem Ġnow ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġin Ġon Batch Scan Results ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġscanner . flush Pending Scan Results ( scan Callback ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstop Scan () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstart Scan () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ}, ĠTimeUnit . SECONDS . to Millis ( 2 0 )) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġstop Scan () Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠUse Ġtry Ġcatch Ġto Ġhandle ĠDead Object Ġexception ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġscanner . stop Scan ( scan Callback ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . i ( TAG , Ġ" Stopped Ġscan ") ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( exception : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . e ( TAG , Ġ" Stop Ġscan Ġfailed : Ġ$ exception ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġvar Ġscan Callback Ġ= Ġobject Ġ: ĠScan Callback () Ġ{ ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Scan Failed ( errorCode : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsuper . on Scan Failed ( errorCode ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . e ( TAG , Ġ" on Scan Failed ĠerrorCode =$ errorCode ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( errorCode Ġ== ĠSC AN _ FAILED _ APPLICATION _ REGISTR ATION _ FAILED ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstart Scan () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Batch Scan Results ( results : ĠMutable List < Scan Result > ?) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsuper . on Batch Scan Results ( results ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" on Batch Scan Results : Ġ${ results ?. size }") ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠSearch Ġfor Ġa ĠT CN Ġin Ġthe Ġservice Ġdata Ġof Ġthe Ġad vertisement ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresults ?. forEach Ġfor _ each @{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" result =$ it ") ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġscan Record Ġ= Ġit . scan Record Ġ?: Ġreturn @ for _ each ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġt cn Service Data Ġ= Ġscan Record . service Data [ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠParcel Uuid ( T cn Constants . UUID _ SERVICE )] ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġhint Is Android Ġ= Ġ( t cn Service Data Ġ!= Ġnull ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠUpdate Ġestimated Ġdistance ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġestimated Distance Met ers Ġ= Ġget Est imated Distance Met ers ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . rssi , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġget Measured RSS I At One Meter ( scan Record . tx Power Level , Ġhint Is Android ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġestimated Distance To Remote Device Address Map [ it . device . address ] Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġestimated Distance Met ers ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġt cn Service Data Ġ?: Ġreturn @ for _ each ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( t cn Service Data . size Ġ< ĠT cn Constants . TEMP OR ARY _ CONTACT _ NUMBER _ LENGTH ) Ġreturn @ for _ each ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġt cn Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġt cn Service Data . slice Array ( 0 Ġuntil ĠT cn Constants . TEMP OR ARY _ CONTACT _ NUMBER _ LENGTH ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . i ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTAG , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Did Ġfind ĠT CN =${ Base 6 4 . encode ToString ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġt cn , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠBase 6 4 . NO _ WRAP ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ)} Ġfrom Ġdevice =${ it . device . address }\" Ġat Ġestimated Ġdistance =${ estimated Distance To Remote Device Address Map [ it . device . address ]}" ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġt cn Callback . on T cn Found ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġt cn , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġestimated Distance To Remote Device Address Map [ it . device . address ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠRemove ĠT CN s Ġfrom Ġour Ġadvertising Ġqueue Ġthat Ġwe Ġreceived Ġfrom Ġdevices Ġwhich Ġare Ġnow ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġout Ġof Ġrange . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġcurrent InRange Addresses Ġ= Ġresults ?. map NotNull Ġ{ Ġit . device . address Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( current InRange Addresses Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent InRange Addresses Ġ= Ġarray ListOf () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġaddresses ToRemove : ĠMutable List < String > Ġ= Ġmutable ListOf () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġin Range B le Address To T cn Map . keys . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! current InRange Addresses . contains ( it )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġaddresses ToRemove . add ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġaddresses ToRemove . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġt cn Ġ= Ġin Range B le Address To T cn Map [ it ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġde queue From Ad vertising ( t cn ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġin Range B le Address To T cn Map . remove ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠNotify Ġthe ĠAPI Ġuser Ġthat ĠT CN s Ġwhich Ġare Ġleft Ġin Ġthe Ġlist Ġare Ġstill Ġin Ġrange Ġand ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġwe Ġhave Ġjust Ġfound Ġthem Ġagain Ġso Ġit Ġcan Ġtrack Ġthe Ġduration Ġof Ġthe Ġcontact . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġin Range B le Address To T cn Map . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . i ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTAG , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Did Ġfind ĠT CN =${ Base 6 4 . encode ToString ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . value , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠBase 6 4 . NO _ WRAP ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ)} Ġfrom Ġdevice =${ it . key } Ġat Ġestimated Ġdistance =${ estimated Distance To Remote Device Address Map [ it . key ]}" ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġt cn Callback . on T cn Found ( it . value , Ġestimated Distance To Remote Device Address Map [ it . key ]) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġstart Ad vertising () Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! is Started ) Ġreturn ĊĠĠĠĠĠĠĠ Ġ// ĠUse Ġtry Ġcatch Ġto Ġhandle ĠDead Object Ġexception ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsettings Ġ= ĠAd vertise Settings . Builder () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Ad vertise Mode ( Ad vertise Settings . AD VER TI SE _ MODE _ LOW _ LAT ENCY ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Tx Power Level ( Ad vertise Settings . AD VER TI SE _ TX _ POWER _ MEDIUM ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Connect able ( true ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. setTimeout ( 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdata Ġ= ĠAd vertise Data . Builder () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Include Device Name ( false ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. add Service Uuid ( Parcel Uuid ( T cn Constants . UUID _ SERVICE )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. add Service Data ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠParcel Uuid ( T cn Constants . UUID _ SERVICE ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠAttach Ġthe Ġfirst Ġ 4 Ġbytes Ġof Ġour ĠT CN Ġto Ġwork Ġaround Ġthe Ġproblem Ġof ĠiOS ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġdevices Ġwriting Ġa Ġnew ĠT CN Ġto Ġus Ġwhenever Ġwe Ġrotate Ġthe ĠT CN Ġ( every Ġ 2 0 Ġsec ). ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠiOS Ġdevices Ġuse Ġthe Ġlast Ġ 4 Ġbytes Ġto Ġidentify Ġthe ĠAndroid Ġdevices Ġand Ġwrite ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġonly Ġonce Ġa ĠT CN Ġto Ġthem . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġt cn Ad vertising Queue . first () Ġ+ Ġgenerated T cn . slice Array ( 0 .. 3 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġadvert iser . start Ad vertising ( settings , Ġdata , Ġadvertising Callback ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . i ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTAG , Ġ" Started Ġadvertising ĠT CN =${ Base 6 4 . encode ToString ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġt cn Ad vertising Queue . first (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠBase 6 4 . NO _ WRAP ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ)} Ġis Own =${ t cn Ad vertising Queue . first (). content Equals ( generated T cn )}" ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( exception : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . e ( TAG , Ġ" Start Ġadvertising Ġfailed : Ġ$ exception ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstart Ad vertising () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġinit B le Gatt Server ( ĊĠĠĠĠĠĠĠ Ġbluetooth Manager : ĠBluetooth Manager , ĊĠĠĠĠĠĠĠ Ġservice UUID : ĠUUID ? ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġbluetooth Gatt Server Ġ= Ġbluetooth Manager . open Gatt Server ( context , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġobject Ġ: ĠBluetooth Gatt Server Callback () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Characteristic Write Request ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdevice : ĠBluetooth Device ?, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠrequestId : ĠInt , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcharacteristic : ĠBluetooth GattCharacteristic ?, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprepared Write : ĠBoolean , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresponse Needed : ĠBoolean , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoffset : ĠInt , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvalue : ĠByteArray ? ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġresult Ġ= ĠBluetooth Gatt . G ATT _ SUCCESS ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( character istic ?. uuid Ġ== ĠT cn Constants . UUID _ CHARACTER ISTIC ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( offset Ġ!= Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresult Ġ= ĠBluetooth Gatt . G ATT _ INVALID _ OFFSET ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( value Ġ== Ġnull Ġ|| Ġvalue . size Ġ!= ĠT cn Constants . TEMP OR ARY _ CONTACT _ NUMBER _ LENGTH ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresult Ġ= ĠBluetooth Gatt . G ATT _ FAILURE ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . i ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTAG , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Did Ġfind ĠT CN =${ Base 6 4 . encode ToString ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvalue , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠBase 6 4 . NO _ WRAP ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ)} Ġfrom Ġdevice =${ device ?. address } Ġat Ġestimated Ġdistance =${ estimated Distance To Remote Device Address Map [ device ?. address ]}" ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġt cn Callback . on T cn Found ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvalue , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġestimated Distance To Remote Device Address Map [ device ?. address ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠT CN s Ġreceived Ġthrough Ġcharacteristic Ġwrites Ġcome Ġfrom ĠiOS Ġapps Ġin Ġthe ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġbackground . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWe Ġact Ġas Ġa Ġbridge Ġand Ġad vertise Ġthese ĠT CN s Ġso ĠiOS Ġapps Ġcan Ġdiscover ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġeach Ġother Ġwhile Ġin Ġthe Ġbackground . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( device Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġin Range B le Address To T cn Map [ device . address ] Ġ= Ġvalue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġenqueue For Ad vertising ( value ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresult Ġ= ĠBluetooth Gatt . G ATT _ FAILURE ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( exception : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresult Ġ= ĠBluetooth Gatt . G ATT _ FAILURE ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . i ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTAG , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" on Characteristic Write Request Ġresult =$ result Ġdevice =$ device ĠrequestId =$ requestId Ġcharacteristic =$ character istic Ġprepared Write =$ prepared Write Ġresponse Needed =$ response Needed Ġoffset =$ offset Ġvalue =$ value " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( response Needed ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbluetooth Gatt Server ?. send Response ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdevice , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠrequestId , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresult , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoffset , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĊĠĠĠĠĠĠĠ Ġval Ġservice Ġ= ĠBluetooth Gatt Service ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġservice UUID , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠBluetooth Gatt Service . SERVICE _ TYPE _ PRIMARY ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġservice . add Characteristic ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠBluetooth GattCharacteristic ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠT cn Constants . UUID _ CHARACTER ISTIC , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠBluetooth GattCharacteristic . PROPERTY _ READ Ġor ĠBluetooth GattCharacteristic . PROPERTY _ WRITE , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠBluetooth GattCharacteristic . PERMISSION _ READ Ġor ĠBluetooth GattCharacteristic . PERMISSION _ WRITE ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠ Ġbluetooth Gatt Server ?. clear Services () ĊĠĠĠĠĠĠĠ Ġbluetooth Gatt Server ?. add Service ( service ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġval Ġadvertising Callback : ĠAd vertise Callback Ġ= Ġobject Ġ: ĠAd vertise Callback () Ġ{ ĊĠĠĠĠĠĠĠ Ġoverride Ġfun ĠonStart Success ( settings In Effect : ĠAd vertise Settings ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . w ( TAG , Ġ" onStart Success Ġsettings In Effect =$ settings In Effect ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsuper . onStart Success ( settings In Effect ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun ĠonStart Failure ( errorCode : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . e ( TAG , Ġ" onStart Failure ĠerrorCode =$ errorCode ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsuper . onStart Failure ( errorCode ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġstop Ad vertising () Ġ{ ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadvert iser . stop Ad vertising ( ad vertising Callback ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . i ( TAG , Ġ" Stopped Ġadvertising ") ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( exception : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . e ( TAG , Ġ" Stop Ġadvertising Ġfailed : Ġ$ exception ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠTAG Ġ= Ġ" T cn Bluetooth Service " ĊĠĠĠ Ġ} Ċ } Ċ