@@ -6,6 +6,7 @@ import android.bluetooth.BluetoothDevice
66import android.bluetooth.BluetoothGatt
77import android.bluetooth.BluetoothGattCallback
88import android.bluetooth.BluetoothGattCharacteristic
9+ import android.bluetooth.BluetoothGattDescriptor
910import android.bluetooth.BluetoothManager
1011import android.bluetooth.BluetoothProfile
1112import android.bluetooth.le.ScanCallback
@@ -14,20 +15,16 @@ import android.bluetooth.le.ScanResult
1415import android.bluetooth.le.ScanSettings
1516import android.content.Context
1617import android.os.Build
17- import android.os.SystemClock
1818import androidx.annotation.RequiresPermission
1919import androidx.appcompat.app.AppCompatActivity
20- import androidx.core.util.forEach
21- import androidx.core.util.isNotEmpty
2220import hmju.http.tracking_interceptor.TrackingDataManager
23- import hmju.http.tracking_interceptor.model.ChildModel
24- import hmju.http.tracking_interceptor.model.ContentsModel
25- import hmju.http.tracking_interceptor.model.SummaryModel
26- import hmju.http.tracking_interceptor.model.TitleModel
27- import hmju.http.tracking_interceptor.model.TrackingModel
21+ import hmju.tracking.hardware.HardwareTrackingModel
2822import timber.log.Timber
23+ import java.nio.ByteBuffer
2924import java.text.SimpleDateFormat
3025import java.util.Locale
26+ import java.util.UUID
27+ import java.util.concurrent.Executors
3128
3229
3330class BleTestProvider (
@@ -117,24 +114,23 @@ class BleTestProvider(
117114
118115 override fun onScanResult (callbackType : Int , result : ScanResult ? ) {
119116 if (result == null ) return
120- // if (!duplicationSet.contains(result.device.address)) {
121- // duplicationSet.add(result.device.address)
122- // TrackingDataManager.getInstance().add(getBleTrackingModel(result, dateFmt))
123- // }
124- TrackingDataManager .getInstance().add(getBleTrackingModel(result, dateFmt))
117+ if (! duplicationSet.contains(result.device.address)) {
118+ duplicationSet.add(result.device.address)
119+ TrackingDataManager .getInstance().add(HardwareTrackingModel (result))
120+ }
125121 }
126122
127123 override fun onBatchScanResults (results : MutableList <ScanResult >? ) {
128124 if (results == null ) return
129- results.forEach {result ->
130- TrackingDataManager .getInstance().add(getBleTrackingModel (result, dateFmt ))
125+ results.forEach { result ->
126+ TrackingDataManager .getInstance().add(HardwareTrackingModel (result))
131127 }
132128 }
133129 }
134130 val setting = ScanSettings .Builder ()
135131 .setNumOfMatches(ScanSettings .MATCH_NUM_MAX_ADVERTISEMENT )
136132 .setScanMode(ScanSettings .SCAN_MODE_LOW_LATENCY )
137- .setReportDelay(1000 )
133+ // .setReportDelay(1000)
138134 .build()
139135
140136 val filter = ScanFilter .Builder ()
@@ -145,18 +141,64 @@ class BleTestProvider(
145141 }
146142
147143 @SuppressLint(" MissingPermission" )
148- private fun startConnection (
149- macAddress : String
144+ fun startConnection (
145+ macAddress : String ,
146+ findUuid : String
150147 ) {
151148 val callback = object : BleGattCallback () {
152149 override fun onConnected (gatt : BluetoothGatt ) {
153- connectionSet.add(macAddress)
154- Timber .d(" μ°κ²° μλ£ λμμ΅λλ€. $macAddress μ°κ²°λ κ°μ:${connectionSet.size} " )
150+ Timber .d(" onConnected $gatt " )
155151 }
156152
157153 override fun onDisconnected (gatt : BluetoothGatt ) {
158- connectionSet.remove(macAddress)
159- Timber .d(" μ°κ²° ν΄μ λμμ΅λλ€. $macAddress μ°κ²°λ κ°μ:${connectionSet.size} " )
154+ Timber .d(" onDisconnected $gatt " )
155+ }
156+
157+ override fun onServicesDiscovered (gatt : BluetoothGatt ) {
158+ var characteristic: BluetoothGattCharacteristic ? = null
159+ for (service in gatt.services) {
160+ for (character in service.characteristics) {
161+ val uuid = character.uuid.toString().uppercase()
162+ if (findUuid.contains(uuid) || uuid.contains(findUuid)) {
163+ characteristic = character
164+ break
165+ }
166+ }
167+ }
168+ Timber .d(" characteristic μ°Ύμ΅λλ€..$characteristic " )
169+ if (characteristic == null ) return
170+ val writeBytes = ByteBuffer .allocate(2 )
171+ .putShort(10000 .toShort())
172+ .array() + ByteBuffer .allocate(2 )
173+ .putShort(10387 .toShort()).array()
174+ if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .TIRAMISU ) {
175+ Timber .d(" λ°μ΄ν° μ¬μ©ν©λλ€. ${writeBytes.contentToString()} " )
176+ gatt.writeCharacteristic(
177+ characteristic,
178+ writeBytes,
179+ BluetoothGattCharacteristic .WRITE_TYPE_DEFAULT
180+ )
181+ Executors .newSingleThreadExecutor().submit {
182+ Thread .sleep(300 )
183+ gatt.setCharacteristicNotification(characteristic, true )
184+ val descriptor = characteristic.getDescriptor(
185+ UUID .fromString(" 00002902-0000-1000-8000-00805f9b34fb" )
186+ )
187+ gatt.writeDescriptor(
188+ descriptor,
189+ BluetoothGattDescriptor .ENABLE_NOTIFICATION_VALUE
190+ )
191+ }
192+ }
193+ }
194+
195+ override fun onCharacteristicRead (gatt : BluetoothGatt , value : ByteArray ) {
196+ TrackingDataManager .getInstance().add(HardwareTrackingModel (gatt, value))
197+ }
198+
199+ override fun onCharacteristicChanged (gatt : BluetoothGatt , value : ByteArray ) {
200+ Timber .d(" onCharacteristicChanged ${value.contentToString()} " )
201+ TrackingDataManager .getInstance().add(HardwareTrackingModel (gatt, value))
160202 }
161203 }
162204 val device = adapter.getRemoteDevice(macAddress)
@@ -167,78 +209,4 @@ class BleTestProvider(
167209 BluetoothDevice .TRANSPORT_LE
168210 ).also { it.requestMtu(300 ) }
169211 }
170-
171- @SuppressLint(" MissingPermission" )
172- private fun getBleTrackingModel (
173- data : ScanResult ,
174- dateFmt : SimpleDateFormat
175- ): TrackingModel {
176- val bootTimeMillis = System .currentTimeMillis() - SystemClock .elapsedRealtime()
177- val scanTime = bootTimeMillis + (data.timestampNanos / 1_000_000L )
178- val device = data.device
179- val summary = SummaryModel (
180- colorHexCode = " #367CEE" ,
181- titleList = listOf (
182- " πBLE" ,
183- " Advertising" ,
184- dateFmt.format(scanTime)
185- ),
186- contentsList = listOf (
187- if (! device.name.isNullOrEmpty()) device.name else " Unknown" ,
188- device.address,
189- " ${data.rssi} dBm"
190- )
191- )
192- val req = mutableSetOf<ChildModel >()
193- req.add(TitleModel (" #C62828" , " [Device]" ))
194- if (! device.name.isNullOrEmpty()) {
195- req.add(ContentsModel (text = " Name:${device.name} " ))
196- }
197- req.add(ContentsModel (hexCode = " #222222" , text = device.address))
198- when (device.type) {
199- BluetoothDevice .DEVICE_TYPE_LE -> " Low Energy"
200- BluetoothDevice .DEVICE_TYPE_DUAL -> " Dual Mode"
201- BluetoothDevice .DEVICE_TYPE_CLASSIC -> " Classic"
202- BluetoothDevice .DEVICE_TYPE_UNKNOWN -> " Unknown"
203- else -> " Invalid"
204- }.run { req.add(ContentsModel (hexCode = " #222222" , text = " Device type:${this } " )) }
205- req.add(ContentsModel (hexCode = " #222222" , text = " πΆ${data.rssi} dBm" ))
206- if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .O ) {
207- val phy = when (data.primaryPhy) {
208- BluetoothDevice .PHY_LE_1M -> " LE 1M"
209- BluetoothDevice .PHY_LE_2M -> " LE 2M"
210- BluetoothDevice .PHY_LE_CODED -> " LE Coded"
211- else -> " Unknown"
212- }
213- req.add(ContentsModel (hexCode = " #222222" , text = " Phy:${phy} " ))
214- req.add(ContentsModel (text = " Connectable:${data.isConnectable} " ))
215- }
216- val scanRecord = data.scanRecord
217- if (scanRecord != null ) {
218- req.add(TitleModel (" #C62828" , " [UUID]" ))
219- if (! scanRecord.serviceUuids.isNullOrEmpty()) {
220- scanRecord.serviceUuids.forEach {
221- req.add(ContentsModel (hexCode = " #222222" , text = it.uuid.toString()))
222- }
223- }
224- if (scanRecord.manufacturerSpecificData.isNotEmpty()) {
225- req.add(TitleModel (" #C62828" , " [Manufacture]" ))
226- scanRecord.manufacturerSpecificData.forEach { key, value ->
227- ContentsModel (
228- hexCode = " #222222" ,
229- text = " ID:${String .format(" 0x%04X" , key)} "
230- ).run { req.add(this ) }
231- ContentsModel (
232- hexCode = " #222222" ,
233- text = value.joinToString { String .format(" %02X" , it) }
234- ).run { req.add(this ) }
235- }
236- }
237- }
238- return TrackingModel (
239- req = req.toList(),
240- res = listOf (),
241- summary = summary
242- )
243- }
244212}
0 commit comments