1 package jp.osdn.gokigen.thetathoughtshutter.bluetooth.connection.eeg
3 import android.app.Activity
4 import android.bluetooth.BluetoothDevice
5 import android.bluetooth.BluetoothSocket
6 import android.content.BroadcastReceiver
7 import android.content.Context
8 import android.content.Intent
9 import android.content.IntentFilter
10 import android.util.Log
11 import jp.osdn.gokigen.thetathoughtshutter.bluetooth.connection.IBluetoothScanResult
12 import jp.osdn.gokigen.thetathoughtshutter.bluetooth.connection.BluetoothDeviceFinder
13 import jp.osdn.gokigen.thetathoughtshutter.brainwave.BrainwaveFileLogger
14 import jp.osdn.gokigen.thetathoughtshutter.brainwave.IBrainwaveDataReceiver
15 import java.io.ByteArrayOutputStream
16 import java.io.InputStream
18 import kotlin.experimental.and
20 class MindWaveConnection(private val activity : Activity, private val dataReceiver: IBrainwaveDataReceiver, private val scanResult: IBluetoothScanResult? = null) : IBluetoothScanResult
24 private val TAG = MindWaveConnection::class.java.simpleName
27 private val deviceFinder = BluetoothDeviceFinder(activity, this)
28 private var fileLogger: BrainwaveFileLogger? = null
29 private var foundDevice = false
30 private var isPairing = false
31 private var loggingFlag = false
32 private var targetDevice: BluetoothDevice? = null
34 private var connectionReceiver = object : BroadcastReceiver()
36 override fun onReceive(context: Context, intent: Intent)
38 onReceiveBroadcastOfConnection(this, context, intent)
42 fun connect(deviceName: String, loggingFlag: Boolean = false)
44 Log.v(TAG, " BrainWaveMobileCommunicator::connect() : $deviceName Logging : $loggingFlag")
49 this.loggingFlag = loggingFlag
51 // Bluetooth のサービスを取得、BLEデバイスをスキャンする
54 deviceFinder.startScan(deviceName)
62 private fun registerReceiver()
66 val filter = IntentFilter()
67 filter.addAction(BluetoothDevice.ACTION_PAIRING_REQUEST)
68 filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED)
69 activity.registerReceiver(connectionReceiver, filter)
77 private fun unregisterReceiver()
81 activity.unregisterReceiver(connectionReceiver)
89 private fun parseReceivedData(data: ByteArray)
96 // ヘッダ部しか入っていない...無視する
100 if (data.size < length + 2)
102 // データが最小サイズに満たない...無視する
105 if (data.size == 8 || data.size == 9)
107 var value: Int = (data[5] and 0xff.toByte()) * 256 + (data[6] and 0xff.toByte())
112 dataReceiver.receivedRawData(value)
115 dataReceiver.receivedSummaryData(data)
118 fileLogger?.outputSummaryData(data)
126 private fun serialCommunicationMain(btSocket: BluetoothSocket)
128 Log.v(TAG, "serialCommunicationMain ")
129 var inputStream: InputStream? = null
133 inputStream = btSocket.inputStream
137 Log.e(TAG, "Fail to accept.", e)
139 if (inputStream == null)
147 // ログ出力を指示されていた場合...ファイル出力クラスを作成しておく
148 fileLogger = BrainwaveFileLogger()
157 var previousData = 0xff.toByte()
158 val outputStream = ByteArrayOutputStream()
163 val data: Int = inputStream.read()
164 Log.v(TAG, " RECEIVED ")
165 val byteData = (data and 0xff).toByte()
166 if (previousData == byteData && byteData == 0xaa.toByte())
168 // 先頭データを見つけた。 (0xaa 0xaa がヘッダ)
169 parseReceivedData(outputStream.toByteArray())
171 outputStream.write(0xaa)
172 outputStream.write(0xaa)
176 outputStream.write(byteData.toInt())
178 previousData = byteData
196 override fun foundBluetoothDevice(device: BluetoothDevice)
200 Log.v(TAG, " foundBluetoothDevice : ${device.name} : ${device.bondState}")
202 deviceFinder.stopScan()
204 if (device.bondState == BluetoothDevice.BOND_BONDED)
207 Log.v(TAG, " ALREADY PAIRED ")
209 targetDevice = device
210 connectBluetoothDevice(device)
214 if ((!foundDevice)&&(!isPairing))
216 Log.v(TAG, "START PAIRING ${device.name}")
217 device.setPin(byteArrayOf(0x30, 0x30, 0x30, 0x30))
218 targetDevice = device
222 deviceFinder.stopScan()
224 catch (e : Exception)
228 //return (device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB")))
233 private fun prepareBluetoothDevice(device: BluetoothDevice) : BluetoothSocket?
237 device.setPin(byteArrayOf(0x30,0x30, 0x30, 0x30))
239 val result = device.createBond()
248 catch (e : Exception)
252 return (device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB")))
255 override fun foundBluetoothDevice(device: BluetoothDevice)
259 Log.v(TAG, " foundBluetoothDevice : ${device.name}")
263 Log.v(TAG, " ALREADY FIND BLUETOOTH DEVICE. : $device.name")
264 deviceFinder.stopScan()
268 deviceFinder.stopScan()
270 val btSocket = prepareBluetoothDevice(device) // device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"))
271 val thread = Thread {
274 if (btSocket != null)
276 serialCommunicationMain(btSocket)
284 if (btSocket != null)
290 Log.v(TAG, " btSocket is NULL.")
292 scanResult?.foundBluetoothDevice(device)
301 private fun connectBluetoothDevice(device : BluetoothDevice?)
305 Log.v(TAG, "connectBluetoothDevice() : ${device?.name}")
308 Log.v(TAG, " DEVICE IS NULL...")
312 val btSocket = device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"))
313 val thread = Thread {
316 if (btSocket != null)
318 serialCommunicationMain(btSocket)
326 if (btSocket != null)
332 Log.v(TAG, " btSocket is NULL.")
334 scanResult?.foundBluetoothDevice(device)
342 override fun notFindBluetoothDevice()
344 Log.v(TAG, " notFindBluetoothDevice()")
345 scanResult?.notFindBluetoothDevice()
346 deviceFinder.stopScan()
353 private fun onReceiveBroadcastOfConnection(receiver: BroadcastReceiver, context: Context, intent: Intent)
355 val action = intent.action
358 Log.v(TAG, "intent.getAction() : null")
363 if (action == BluetoothDevice.ACTION_PAIRING_REQUEST)
365 val device = intent.getParcelableExtra<BluetoothDevice>(BluetoothDevice.EXTRA_DEVICE)!!
366 Log.v(TAG, " onReceiveBroadcastOfConnection : BluetoothDevice.ACTION_PAIRING_REQUEST device: ${device.name}")
369 targetDevice?.setPin(byteArrayOf(0x30,0x30, 0x30, 0x30))
370 device.setPin(byteArrayOf(0x30,0x30, 0x30, 0x30))
371 receiver.abortBroadcast()
373 catch (e : Exception)
378 else if (action == BluetoothDevice.ACTION_BOND_STATE_CHANGED)
380 val device = intent.getParcelableExtra<BluetoothDevice>(BluetoothDevice.EXTRA_DEVICE)!!
381 val bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, -1)
382 Log.v(TAG, " onReceiveBroadcastOfConnection : BluetoothDevice.ACTION_BOND_STATE_CHANGED ($bondState) device: ${device.name}")
383 if (bondState == BluetoothDevice.BOND_BONDED)
386 Log.v(TAG, " ----- Device is Paired! ${device.name}")
388 connectBluetoothDevice(device)
394 Log.w(TAG, "onReceiveBroadcastOfConnection() EXCEPTION" + e.message)