Compare commits
	
		
			No commits in common. "4cdaceda76013999ca0e81d6ddd6eeec8c596f0d" and "2af636b9461a06fb664b746cb6b6b200da187aa4" have entirely different histories.
		
	
	
		
			4cdaceda76
			...
			2af636b946
		
	
		
							
								
								
									
										267
									
								
								BleConnect.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										267
									
								
								BleConnect.java
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,267 @@
 | 
				
			||||||
 | 
					package st.wow.git.ble;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.lang.Runnable;
 | 
				
			||||||
 | 
					import java.lang.String;
 | 
				
			||||||
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					import java.util.UUID;
 | 
				
			||||||
 | 
					import android.util.Log;
 | 
				
			||||||
 | 
					import java.lang.Class;
 | 
				
			||||||
 | 
					import java.lang.ClassLoader;
 | 
				
			||||||
 | 
					import java.lang.reflect.Constructor;
 | 
				
			||||||
 | 
					import android.app.Activity;
 | 
				
			||||||
 | 
					import android.app.Fragment;
 | 
				
			||||||
 | 
					import android.os.Handler;
 | 
				
			||||||
 | 
					import android.bluetooth.BluetoothAdapter;
 | 
				
			||||||
 | 
					import android.bluetooth.BluetoothDevice;
 | 
				
			||||||
 | 
					import android.bluetooth.BluetoothGatt;
 | 
				
			||||||
 | 
					import android.bluetooth.BluetoothGattCallback;
 | 
				
			||||||
 | 
					import android.bluetooth.BluetoothGattDescriptor;
 | 
				
			||||||
 | 
					import android.bluetooth.BluetoothGattService;
 | 
				
			||||||
 | 
					import android.bluetooth.BluetoothGattCharacteristic;
 | 
				
			||||||
 | 
					import android.bluetooth.BluetoothManager;
 | 
				
			||||||
 | 
					import android.bluetooth.BluetoothProfile;
 | 
				
			||||||
 | 
					import android.content.BroadcastReceiver;
 | 
				
			||||||
 | 
					import android.content.Context;
 | 
				
			||||||
 | 
					import android.content.Intent;
 | 
				
			||||||
 | 
					import android.content.IntentFilter;
 | 
				
			||||||
 | 
					import android.content.pm.PackageManager;
 | 
				
			||||||
 | 
					import android.Manifest;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class BleConnect extends Fragment {
 | 
				
			||||||
 | 
						BluetoothManager manager;
 | 
				
			||||||
 | 
						BluetoothAdapter adapter;
 | 
				
			||||||
 | 
						Handler handler;
 | 
				
			||||||
 | 
						boolean wantScan = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						final int PERMISSION_REQUEST = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						final int REQUEST_ENABLE_BT = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public BleConnect() {
 | 
				
			||||||
 | 
							Log.d("gio", "BleConnect()");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@Override public void onAttach(Context ctx) {
 | 
				
			||||||
 | 
							super.onAttach(ctx);
 | 
				
			||||||
 | 
							Log.d("gio", "BleConnect: onAttach()");
 | 
				
			||||||
 | 
							ctx.registerReceiver(receiver, new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED));
 | 
				
			||||||
 | 
							manager = (BluetoothManager) ctx.getSystemService(ctx.BLUETOOTH_SERVICE);
 | 
				
			||||||
 | 
							adapter = manager.getAdapter();
 | 
				
			||||||
 | 
							handler = new Handler(ctx.getMainLooper());
 | 
				
			||||||
 | 
							if (!enabled()) {
 | 
				
			||||||
 | 
								Log.d("gio", "BleConnect: enabling adapter");
 | 
				
			||||||
 | 
								Intent enableBtIntent = new Intent(adapter.ACTION_REQUEST_ENABLE);
 | 
				
			||||||
 | 
								handler.post(new Runnable() {
 | 
				
			||||||
 | 
									public void run() {
 | 
				
			||||||
 | 
										startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								Log.d("gio", "BleConnect: adapter is enabled");
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (ctx.checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
 | 
				
			||||||
 | 
					                        requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSION_REQUEST);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
							installComplete(this);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public boolean enabled() {
 | 
				
			||||||
 | 
							return (adapter != null && adapter.isEnabled());
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private final BroadcastReceiver receiver = new BroadcastReceiver() {
 | 
				
			||||||
 | 
							@Override
 | 
				
			||||||
 | 
							public void onReceive(Context context, Intent intent) {
 | 
				
			||||||
 | 
								Log.d("gio", "Received broadcast");
 | 
				
			||||||
 | 
								if (intent.getAction().equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
 | 
				
			||||||
 | 
									updateState(intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1));
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@Override
 | 
				
			||||||
 | 
						public void onDestroy() {
 | 
				
			||||||
 | 
							Log.d("gio","onDestroy()");
 | 
				
			||||||
 | 
							stopScan();
 | 
				
			||||||
 | 
							getContext().unregisterReceiver(receiver);
 | 
				
			||||||
 | 
							super.onDestroy();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private final BluetoothAdapter.LeScanCallback scanCallback = new BluetoothAdapter.LeScanCallback() {
 | 
				
			||||||
 | 
							public void onLeScan(final BluetoothDevice dev, int rssi, byte[] scanRecord) {
 | 
				
			||||||
 | 
								Log.d("gio","onLeScan(): " + dev.getName());
 | 
				
			||||||
 | 
								onScan(dev.getName(), dev.getAddress(), rssi, dev);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public void scan() {
 | 
				
			||||||
 | 
							if (!enabled() || getContext().checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
 | 
				
			||||||
 | 
								Log.d("gio","BleConnect: scan() not enabled or no permissions, wantScan = true");
 | 
				
			||||||
 | 
								wantScan = true;
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							Log.d("gio","BleConnect: scan() starting scan");
 | 
				
			||||||
 | 
							wantScan = false;
 | 
				
			||||||
 | 
							handler.post(new Runnable() {
 | 
				
			||||||
 | 
								public void run() {
 | 
				
			||||||
 | 
									adapter.startLeScan(scanCallback);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public void stopScan() {
 | 
				
			||||||
 | 
							if (!enabled()) {
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							Log.d("gio", "Stop scan");
 | 
				
			||||||
 | 
							handler.post(new Runnable() {
 | 
				
			||||||
 | 
								public void run() {
 | 
				
			||||||
 | 
									adapter.stopLeScan(scanCallback);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private final BluetoothGattCallback gattCallback = new BluetoothGattCallback() {
 | 
				
			||||||
 | 
					@Override
 | 
				
			||||||
 | 
							public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
 | 
				
			||||||
 | 
								switch (newState) {
 | 
				
			||||||
 | 
									case BluetoothProfile.STATE_CONNECTED: {
 | 
				
			||||||
 | 
										BluetoothDevice device = gatt.getDevice();
 | 
				
			||||||
 | 
										Log.d("gio", "Connected");
 | 
				
			||||||
 | 
										String addr = device.getAddress();
 | 
				
			||||||
 | 
										Log.d("gio", "Address = " + addr);
 | 
				
			||||||
 | 
										onConnect(gatt, device.getAddress());
 | 
				
			||||||
 | 
										break;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									case BluetoothProfile.STATE_DISCONNECTED: {
 | 
				
			||||||
 | 
										Log.d("gio", "Disconnected");
 | 
				
			||||||
 | 
										break;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									default: {
 | 
				
			||||||
 | 
										Log.d("gio", "onConnectionStateChange: unknown state");
 | 
				
			||||||
 | 
										break;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							public void onServicesDiscovered(BluetoothGatt gatt, int status) {
 | 
				
			||||||
 | 
								for (BluetoothGattService serv : gatt.getServices()) {
 | 
				
			||||||
 | 
									onDiscoverService(gatt.getDevice().getAddress(), serv.getUuid().toString(), serv);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic chr) {
 | 
				
			||||||
 | 
								byte[] v = chr.getValue();
 | 
				
			||||||
 | 
								characteristicChanged(gatt.getDevice().getAddress(), chr.getUuid().toString(), chr, v, v.length);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public void connect(BluetoothDevice dev) {
 | 
				
			||||||
 | 
							if (dev == null) {
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							Log.d("gio","BleConnect: connect");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							handler.post(new Runnable() {
 | 
				
			||||||
 | 
								public void run() {
 | 
				
			||||||
 | 
									dev.connectGatt(getContext(), false, gattCallback, BluetoothDevice.TRANSPORT_LE);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public void disconnect(BluetoothGatt gatt) {
 | 
				
			||||||
 | 
							if (gatt == null) {
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							Log.d("gio","BleConnect: disconnect");
 | 
				
			||||||
 | 
							handler.post(new Runnable() {
 | 
				
			||||||
 | 
								public void run() {
 | 
				
			||||||
 | 
									gatt.disconnect();
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public void discoverServices(BluetoothGatt gatt) {
 | 
				
			||||||
 | 
							if (gatt == null) {
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							handler.post(new Runnable() {
 | 
				
			||||||
 | 
								public void run() {
 | 
				
			||||||
 | 
									gatt.discoverServices();
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public void discoverCharacteristics(BluetoothGatt gatt, BluetoothGattService serv) {
 | 
				
			||||||
 | 
							Log.d("gio","BleConnect: discoverCharacteristics()");
 | 
				
			||||||
 | 
							if (gatt == null) {
 | 
				
			||||||
 | 
								Log.d("gio","BleConnect: gatt == null");
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							List<BluetoothGattCharacteristic> chrs = serv.getCharacteristics();
 | 
				
			||||||
 | 
							if (chrs.isEmpty()) {
 | 
				
			||||||
 | 
								Log.d("gio", "BleConnect: no characteristics found!");
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							for (BluetoothGattCharacteristic chr : chrs) {
 | 
				
			||||||
 | 
								Log.d("gio","BleConnect: -- " + chr.getUuid().toString());
 | 
				
			||||||
 | 
								onDiscoverCharacteristic(gatt.getDevice().getAddress(), serv.getUuid().toString(), serv, chr.getUuid().toString(), chr);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public void setCharacteristicNotification(BluetoothGatt gatt, BluetoothGattCharacteristic chr) {
 | 
				
			||||||
 | 
							gatt.setCharacteristicNotification(chr, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							BluetoothGattDescriptor descriptor = chr.getDescriptor(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb")); // Client Characteristic Config
 | 
				
			||||||
 | 
							descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
 | 
				
			||||||
 | 
							gatt.writeDescriptor(descriptor);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@Override public void onActivityResult(int requestCode, int resultCode, Intent data) {
 | 
				
			||||||
 | 
							Log.d("gio", "BleConnect: onActivityResult()");
 | 
				
			||||||
 | 
							if (requestCode == REQUEST_ENABLE_BT) {
 | 
				
			||||||
 | 
								Log.d("gio", "BleConnect: onActivityResult() REQUEST_ENABLE_BT");
 | 
				
			||||||
 | 
								switch (resultCode) {
 | 
				
			||||||
 | 
									case Activity.RESULT_OK: {
 | 
				
			||||||
 | 
										Log.d("gio", "BleConnect: onActivityResult() -- OK");
 | 
				
			||||||
 | 
										if (wantScan) {
 | 
				
			||||||
 | 
											scan();
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										break;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									case Activity.RESULT_CANCELED: {
 | 
				
			||||||
 | 
										Log.d("gio", "BleConnect: onActivityResult() -- Cancelled");
 | 
				
			||||||
 | 
										break;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@Override
 | 
				
			||||||
 | 
						public void onRequestPermissionsResult (int requestCode, String[] permissions, int[] grantResults) {
 | 
				
			||||||
 | 
							Log.d("gio", "BleConnect: onRequestPermissionsResult");
 | 
				
			||||||
 | 
							if (requestCode == PERMISSION_REQUEST) {
 | 
				
			||||||
 | 
								boolean granted = true;
 | 
				
			||||||
 | 
								for (int x : grantResults) {
 | 
				
			||||||
 | 
									if (x == PackageManager.PERMISSION_DENIED) {
 | 
				
			||||||
 | 
										granted = false;
 | 
				
			||||||
 | 
										break;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (!granted) {
 | 
				
			||||||
 | 
									Log.d("gio", "BleConnect: permissions not granted");
 | 
				
			||||||
 | 
									return;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								Log.d("gio", "BleConnect: permissions granted");
 | 
				
			||||||
 | 
								if (wantScan) {
 | 
				
			||||||
 | 
									scan();
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						static private native void installComplete(BleConnect p);
 | 
				
			||||||
 | 
						static private native void updateState(int s);
 | 
				
			||||||
 | 
						static private native void onScan(String name, String id, int rssi, BluetoothDevice dev);
 | 
				
			||||||
 | 
						static private native void onConnect(BluetoothGatt gatt, String id);
 | 
				
			||||||
 | 
						static private native void onDiscoverService(String id, String uuid, BluetoothGattService serv);
 | 
				
			||||||
 | 
						static private native void onDiscoverCharacteristic(String id, String suuid, BluetoothGattService serv, String cuuid, BluetoothGattCharacteristic chr);
 | 
				
			||||||
 | 
						static private native void characteristicChanged(String id, String cuuid, BluetoothGattCharacteristic chr, byte[] value, int length);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,262 +0,0 @@
 | 
				
			||||||
package st.wow.git.ble;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import java.lang.String;
 | 
					 | 
				
			||||||
import java.util.List;
 | 
					 | 
				
			||||||
import java.util.UUID;
 | 
					 | 
				
			||||||
import android.app.Activity;
 | 
					 | 
				
			||||||
import android.app.Fragment;
 | 
					 | 
				
			||||||
import android.bluetooth.BluetoothAdapter;
 | 
					 | 
				
			||||||
import android.bluetooth.BluetoothGatt;
 | 
					 | 
				
			||||||
import android.bluetooth.BluetoothGattCharacteristic;
 | 
					 | 
				
			||||||
import android.bluetooth.BluetoothGattDescriptor;
 | 
					 | 
				
			||||||
import android.bluetooth.BluetoothGattService;
 | 
					 | 
				
			||||||
import android.bluetooth.BluetoothManager;
 | 
					 | 
				
			||||||
import android.bluetooth.le.ScanResult;
 | 
					 | 
				
			||||||
import android.content.BroadcastReceiver;
 | 
					 | 
				
			||||||
import android.content.Context;
 | 
					 | 
				
			||||||
import android.content.Intent;
 | 
					 | 
				
			||||||
import android.content.IntentFilter;
 | 
					 | 
				
			||||||
import android.content.pm.PackageManager;
 | 
					 | 
				
			||||||
import android.Manifest;
 | 
					 | 
				
			||||||
import android.util.Log;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import com.welie.blessed.BluetoothCentral;
 | 
					 | 
				
			||||||
import com.welie.blessed.BluetoothCentralCallback;
 | 
					 | 
				
			||||||
import com.welie.blessed.BluetoothPeripheral;
 | 
					 | 
				
			||||||
import com.welie.blessed.BluetoothPeripheralCallback;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
public class BlessedConnect extends Fragment {
 | 
					 | 
				
			||||||
	BluetoothCentral central;
 | 
					 | 
				
			||||||
	boolean wantScan = false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	final int PERMISSION_REQUEST = 1;
 | 
					 | 
				
			||||||
	final int REQUEST_ENABLE_BT = 2;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	public BlessedConnect() {
 | 
					 | 
				
			||||||
		Log.d("gio", "BlessedConnect()");
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	@Override public void onAttach(Context ctx) {
 | 
					 | 
				
			||||||
		super.onAttach(ctx);
 | 
					 | 
				
			||||||
		Log.d("gio", "BlessedConnect: onAttach()");
 | 
					 | 
				
			||||||
		ctx.registerReceiver(receiver, new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED));
 | 
					 | 
				
			||||||
		if (ctx.checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
 | 
					 | 
				
			||||||
                        requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSION_REQUEST);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
		central = new BluetoothCentral(ctx, centralCallback, null);
 | 
					 | 
				
			||||||
		installComplete(this);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	private final BroadcastReceiver receiver = new BroadcastReceiver() {
 | 
					 | 
				
			||||||
		@Override
 | 
					 | 
				
			||||||
		public void onReceive(Context context, Intent intent) {
 | 
					 | 
				
			||||||
			Log.d("gio", "Received broadcast");
 | 
					 | 
				
			||||||
			if (intent.getAction().equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
 | 
					 | 
				
			||||||
				updateState(intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1));
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	public boolean enabled() {
 | 
					 | 
				
			||||||
		Context ctx = getContext();
 | 
					 | 
				
			||||||
		//The Blessed library does not expose this functionality, so
 | 
					 | 
				
			||||||
		//we need to get our own BluetoothAdapter and check its status.
 | 
					 | 
				
			||||||
		BluetoothAdapter adapter = ((BluetoothManager)ctx.getSystemService(ctx.BLUETOOTH_SERVICE)).getAdapter();
 | 
					 | 
				
			||||||
		return (adapter != null && adapter.isEnabled());
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	@Override
 | 
					 | 
				
			||||||
	public void onDestroy() {
 | 
					 | 
				
			||||||
		Log.d("gio","onDestroy()");
 | 
					 | 
				
			||||||
		stopScan();
 | 
					 | 
				
			||||||
		getContext().unregisterReceiver(receiver);
 | 
					 | 
				
			||||||
		super.onDestroy();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	public void scan() {
 | 
					 | 
				
			||||||
		central.scanForPeripherals();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	public void stopScan() {
 | 
					 | 
				
			||||||
		central.stopScan();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	private final BluetoothCentralCallback centralCallback = new BluetoothCentralCallback() {
 | 
					 | 
				
			||||||
		@Override
 | 
					 | 
				
			||||||
		public void onDiscoveredPeripheral(BluetoothPeripheral peripheral, ScanResult scanResult) {
 | 
					 | 
				
			||||||
			Log.d("gio", "BlessedConnect: onDiscoveredPeripheral(): " + peripheral.getName());
 | 
					 | 
				
			||||||
			onScan(peripheral.getName(), peripheral.getAddress(), scanResult.getRssi(), peripheral);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		@Override
 | 
					 | 
				
			||||||
		public void onConnectedPeripheral(BluetoothPeripheral peripheral) {
 | 
					 | 
				
			||||||
			Log.d("gio", "BlessedConnect: Connected to " + peripheral.getName());
 | 
					 | 
				
			||||||
			Log.d("gio", "BlessedConnect: Address = " + peripheral.getAddress());
 | 
					 | 
				
			||||||
			onConnect(peripheral, peripheral.getAddress());
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		@Override
 | 
					 | 
				
			||||||
		public void onConnectionFailed(BluetoothPeripheral peripheral, int status) {
 | 
					 | 
				
			||||||
			Log.d("gio", "BlessedConnect: onConnectionFailed()");
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		@Override
 | 
					 | 
				
			||||||
		public void onDisconnectedPeripheral(BluetoothPeripheral peripheral, int status) {
 | 
					 | 
				
			||||||
			Log.d("gio", "BlessedConnect: Disconnected");
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		@Override
 | 
					 | 
				
			||||||
		public void onScanFailed(int errorCode) {
 | 
					 | 
				
			||||||
			Log.d("gio", "BlessedConnect: Scan failed");
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	private final BluetoothPeripheralCallback peripheralCallback = new BluetoothPeripheralCallback() {
 | 
					 | 
				
			||||||
		public void onBondingFailed(BluetoothPeripheral peripheral) {
 | 
					 | 
				
			||||||
			Log.d("gio", "BlessedConnect: onBondingFailed()");
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		public void onBondingStarted(BluetoothPeripheral peripheral) {
 | 
					 | 
				
			||||||
			Log.d("gio", "BlessedConnect: onBondingStarted()");
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		public void onBondingSucceeded(BluetoothPeripheral peripheral) {
 | 
					 | 
				
			||||||
			Log.d("gio", "BlessedConnect: onBondingSucceeded()");
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		public void onBondLost(BluetoothPeripheral peripheral) {
 | 
					 | 
				
			||||||
			Log.d("gio", "BlessedConnect: onBondLost()");
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		public void onCharacteristicUpdate(BluetoothPeripheral peripheral, byte[] value, BluetoothGattCharacteristic characteristic, int status) {
 | 
					 | 
				
			||||||
			Log.d("gio", "BlessedConnect: onCharacteristicUpdate()");
 | 
					 | 
				
			||||||
			characteristicChanged(peripheral.getAddress(), characteristic.getUuid().toString(), characteristic, value, value.length);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		public void onCharacteristicWrite(BluetoothPeripheral peripheral, byte[] value, android.bluetooth.BluetoothGattCharacteristic characteristic, int status) {
 | 
					 | 
				
			||||||
			Log.d("gio", "onCharacteristicWrite(): " + characteristic.getUuid().toString());
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		public void onDescriptorRead(BluetoothPeripheral peripheral, byte[] value, android.bluetooth.BluetoothGattDescriptor descriptor, int status) {
 | 
					 | 
				
			||||||
			Log.d("gio", "onDescriptorRead()");
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		public void onDescriptorWrite(BluetoothPeripheral peripheral, byte[] value, android.bluetooth.BluetoothGattDescriptor descriptor, int status) {
 | 
					 | 
				
			||||||
			Log.d("gio", "onDescriptorWrite(): " + descriptor.getUuid().toString());
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		public void onMtuChanged(BluetoothPeripheral peripheral, int mtu, int status) {
 | 
					 | 
				
			||||||
			Log.d("gio", "onMtuChanged()");
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
 | 
					 | 
				
			||||||
			Log.d("gio", "onReadRemoteRssi");
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		public void onNotificationStateUpdate(BluetoothPeripheral peripheral, BluetoothGattCharacteristic characteristic, int status) {
 | 
					 | 
				
			||||||
			if (status == BluetoothGatt.GATT_SUCCESS) {
 | 
					 | 
				
			||||||
				if(peripheral.isNotifying(characteristic)) {
 | 
					 | 
				
			||||||
					Log.i("gio", String.format("BlessedConnect: Notify set to 'on' for %s", characteristic.getUuid()));
 | 
					 | 
				
			||||||
				} else {
 | 
					 | 
				
			||||||
					Log.i("gio", String.format("BlessedConnect: Notify set to 'off' for %s", characteristic.getUuid()));
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			} else {
 | 
					 | 
				
			||||||
				Log.d("gio", "BlessedConnect: onNotificationStateUpdate(): failed");
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		public void onServicesDiscovered(BluetoothPeripheral peripheral) {
 | 
					 | 
				
			||||||
			Log.d("gio", "BlessedConnect: onServicesDiscovered()");
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	public void connect(BluetoothPeripheral peripheral) {
 | 
					 | 
				
			||||||
		if (peripheral == null) {
 | 
					 | 
				
			||||||
			return;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		Log.d("gio","BlessedConnect: connect");
 | 
					 | 
				
			||||||
		central.connectPeripheral(peripheral, peripheralCallback);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	public void disconnect(BluetoothPeripheral peripheral) {
 | 
					 | 
				
			||||||
		if (peripheral == null) {
 | 
					 | 
				
			||||||
			return;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		Log.d("gio","BlessedConnect: disconnect");
 | 
					 | 
				
			||||||
		peripheral.cancelConnection();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	public void discoverServices(BluetoothPeripheral peripheral) {
 | 
					 | 
				
			||||||
		if (peripheral == null) {
 | 
					 | 
				
			||||||
			return;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		List<BluetoothGattService> services = peripheral.getServices();
 | 
					 | 
				
			||||||
		for (BluetoothGattService serv : services) {
 | 
					 | 
				
			||||||
			onDiscoverService(peripheral.getAddress(), serv.getUuid().toString(), serv);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	public void discoverCharacteristics(BluetoothPeripheral peripheral, BluetoothGattService serv) {
 | 
					 | 
				
			||||||
		if (peripheral == null || serv == null) {
 | 
					 | 
				
			||||||
			return;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		List<BluetoothGattCharacteristic> chrs = serv.getCharacteristics();
 | 
					 | 
				
			||||||
		for (BluetoothGattCharacteristic chr : chrs) {
 | 
					 | 
				
			||||||
			onDiscoverCharacteristic(peripheral.getAddress(), serv.getUuid().toString(), serv, chr.getUuid().toString(), chr);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	public void readCharacteristic(BluetoothPeripheral peripheral, BluetoothGattCharacteristic chr) {
 | 
					 | 
				
			||||||
		if (peripheral == null || chr == null) {
 | 
					 | 
				
			||||||
			return;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		peripheral.readCharacteristic(chr);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	public boolean setCharacteristicNotification(BluetoothPeripheral peripheral, BluetoothGattCharacteristic chr) {
 | 
					 | 
				
			||||||
		if (peripheral == null || chr == null) {
 | 
					 | 
				
			||||||
			return false;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return peripheral.setNotify(chr, true);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	@Override public void onActivityResult(int requestCode, int resultCode, Intent data) {
 | 
					 | 
				
			||||||
		Log.d("gio", "BlessedConnect: onActivityResult()");
 | 
					 | 
				
			||||||
		if (requestCode == REQUEST_ENABLE_BT) {
 | 
					 | 
				
			||||||
			Log.d("gio", "BlessedConnect: onActivityResult() REQUEST_ENABLE_BT");
 | 
					 | 
				
			||||||
			switch (resultCode) {
 | 
					 | 
				
			||||||
				case Activity.RESULT_OK: {
 | 
					 | 
				
			||||||
					Log.d("gio", "BlessedConnect: onActivityResult() -- OK");
 | 
					 | 
				
			||||||
					if (wantScan) {
 | 
					 | 
				
			||||||
						scan();
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
					break;
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				case Activity.RESULT_CANCELED: {
 | 
					 | 
				
			||||||
					Log.d("gio", "BlessedConnect: onActivityResult() -- Cancelled");
 | 
					 | 
				
			||||||
					break;
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	@Override
 | 
					 | 
				
			||||||
	public void onRequestPermissionsResult (int requestCode, String[] permissions, int[] grantResults) {
 | 
					 | 
				
			||||||
		Log.d("gio", "BlessedConnect: onRequestPermissionsResult");
 | 
					 | 
				
			||||||
		if (requestCode == PERMISSION_REQUEST) {
 | 
					 | 
				
			||||||
			boolean granted = true;
 | 
					 | 
				
			||||||
			for (int x : grantResults) {
 | 
					 | 
				
			||||||
				if (x == PackageManager.PERMISSION_DENIED) {
 | 
					 | 
				
			||||||
					granted = false;
 | 
					 | 
				
			||||||
					break;
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if (!granted) {
 | 
					 | 
				
			||||||
				Log.d("gio", "BlessedConnect: permissions not granted");
 | 
					 | 
				
			||||||
				return;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			Log.d("gio", "BlessedConnect: permissions granted");
 | 
					 | 
				
			||||||
			if (wantScan) {
 | 
					 | 
				
			||||||
				scan();
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	static private native void installComplete(BlessedConnect p);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	static private native void updateState(int s);
 | 
					 | 
				
			||||||
	static private native void onScan(String name, String id, int rssi, BluetoothPeripheral peripheral);
 | 
					 | 
				
			||||||
	static private native void onConnect(BluetoothPeripheral peripheral, String id);
 | 
					 | 
				
			||||||
	static private native void onDiscoverService(String id, String uuid, BluetoothGattService serv);
 | 
					 | 
				
			||||||
	static private native void onDiscoverCharacteristic(String id, String suuid, BluetoothGattService serv, String cuuid, BluetoothGattCharacteristic chr);
 | 
					 | 
				
			||||||
	static private native void characteristicChanged(String id, String cuuid, BluetoothGattCharacteristic chr, byte[] value, int length);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,5 @@
 | 
				
			||||||
//go:generate mkdir -p classes
 | 
					//go:generate mkdir -p classes
 | 
				
			||||||
//go:generate javac -bootclasspath $ANDROID_HOME/platforms/android-29/android.jar -classpath blessed-full.jar -d classes BlessedConnect.java
 | 
					//go:generate javac -bootclasspath $ANDROID_HOME/platforms/android-29/android.jar -d classes BleConnect.java
 | 
				
			||||||
//go:generate jar cf Ble.jar -C classes .
 | 
					//go:generate jar cf Ble.jar -C classes .
 | 
				
			||||||
//go:generate rm -rf classes
 | 
					//go:generate rm -rf classes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,7 +24,7 @@ import "C"
 | 
				
			||||||
// Types required for ble.go
 | 
					// Types required for ble.go
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type bleHandle struct {
 | 
					type bleHandle struct {
 | 
				
			||||||
	BlessedConnect C.jobject
 | 
						BleConnect C.jobject
 | 
				
			||||||
	state int
 | 
						state int
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -34,7 +34,8 @@ type Peripheral struct {
 | 
				
			||||||
	Name string
 | 
						Name string
 | 
				
			||||||
	RSSI int
 | 
						RSSI int
 | 
				
			||||||
	Identifier string
 | 
						Identifier string
 | 
				
			||||||
	peripheral C.jobject
 | 
						device C.jobject
 | 
				
			||||||
 | 
						gatt C.jobject
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Service struct {
 | 
					type Service struct {
 | 
				
			||||||
| 
						 | 
					@ -89,17 +90,17 @@ func peripheralLookup(p Peripheral) *BLE {
 | 
				
			||||||
// FIXME: check what happens with "incomplete" Peripherals that have only
 | 
					// FIXME: check what happens with "incomplete" Peripherals that have only
 | 
				
			||||||
// an Identifier set. Do the other functions on Peripherals do something
 | 
					// an Identifier set. Do the other functions on Peripherals do something
 | 
				
			||||||
// sensible?
 | 
					// sensible?
 | 
				
			||||||
func newPeripheral(name, id string, rssi int, peripheral C.jobject) Peripheral {
 | 
					func newPeripheral(name, id string, rssi int, dev C.jobject) Peripheral {
 | 
				
			||||||
	return Peripheral{
 | 
						return Peripheral{
 | 
				
			||||||
		Name: name,
 | 
							Name: name,
 | 
				
			||||||
		RSSI: rssi,
 | 
							RSSI: rssi,
 | 
				
			||||||
		Identifier: id,
 | 
							Identifier: id,
 | 
				
			||||||
		peripheral: peripheral,
 | 
							device: dev,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (p Peripheral) IsIncomplete() bool {
 | 
					func (p Peripheral) IsIncomplete() bool {
 | 
				
			||||||
	if p.peripheral == 0 {
 | 
						if p.device == 0 {
 | 
				
			||||||
		return true
 | 
							return true
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		return false
 | 
							return false
 | 
				
			||||||
| 
						 | 
					@ -131,7 +132,7 @@ func (b *BLE) readyToScan() bool {
 | 
				
			||||||
	connect()
 | 
						connect()
 | 
				
			||||||
	var ret bool
 | 
						var ret bool
 | 
				
			||||||
	runInJVM(func(env *C.JNIEnv) {
 | 
						runInJVM(func(env *C.JNIEnv) {
 | 
				
			||||||
		ret = C.enabled(env, b.handle.BlessedConnect) == C.JNI_TRUE
 | 
							ret = C.enabled(env, b.handle.BleConnect) == C.JNI_TRUE
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
	return ret
 | 
						return ret
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -140,7 +141,7 @@ func (b *BLE) readyToScan() bool {
 | 
				
			||||||
func (b *BLE) scan() {
 | 
					func (b *BLE) scan() {
 | 
				
			||||||
	connect()
 | 
						connect()
 | 
				
			||||||
	runInJVM(func(env *C.JNIEnv) {
 | 
						runInJVM(func(env *C.JNIEnv) {
 | 
				
			||||||
		C.scan(env, b.handle.BlessedConnect);
 | 
							C.scan(env, b.handle.BleConnect);
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -148,14 +149,15 @@ func (b *BLE) scan() {
 | 
				
			||||||
func (b *BLE) stopScan() {
 | 
					func (b *BLE) stopScan() {
 | 
				
			||||||
	connect()
 | 
						connect()
 | 
				
			||||||
	runInJVM(func(env *C.JNIEnv) {
 | 
						runInJVM(func(env *C.JNIEnv) {
 | 
				
			||||||
		C.stopScan(env, b.handle.BlessedConnect);
 | 
							C.stopScan(env, b.handle.BleConnect);
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//connectPeripheral attempts to connect to a Peripheral
 | 
					//connectPeripheral attempts to connect to a Peripheral
 | 
				
			||||||
func (b *BLE) connectPeripheral(x Peripheral) {
 | 
					func (b *BLE) connectPeripheral(x Peripheral) {
 | 
				
			||||||
 | 
						connect()
 | 
				
			||||||
	runInJVM(func(env *C.JNIEnv) {
 | 
						runInJVM(func(env *C.JNIEnv) {
 | 
				
			||||||
		C.connect(env, b.handle.BlessedConnect, x.peripheral)
 | 
							C.connect(env, b.handle.BleConnect, x.device)
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -163,7 +165,7 @@ func (b *BLE) connectPeripheral(x Peripheral) {
 | 
				
			||||||
func (b *BLE) cancelConnection(p Peripheral) {
 | 
					func (b *BLE) cancelConnection(p Peripheral) {
 | 
				
			||||||
	connect()
 | 
						connect()
 | 
				
			||||||
	runInJVM(func(env *C.JNIEnv) {
 | 
						runInJVM(func(env *C.JNIEnv) {
 | 
				
			||||||
		C.disconnect(env, b.handle.BlessedConnect, p.peripheral)
 | 
							C.disconnect(env, b.handle.BleConnect, p.gatt)
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -176,38 +178,33 @@ func (b *BLE) knownPeripheral(p Peripheral) (Peripheral, bool) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//DiscoverServices asks a Peripheral for its Services
 | 
					//DiscoverServices asks a Peripheral for its Services
 | 
				
			||||||
func (p Peripheral) DiscoverServices() {
 | 
					func (p Peripheral) DiscoverServices() {
 | 
				
			||||||
	//launch a goroutine because this function calls back directly
 | 
					 | 
				
			||||||
	//from the same thread (the underlying Java call is synchronous)
 | 
					 | 
				
			||||||
	go func() {
 | 
					 | 
				
			||||||
	connect()
 | 
						connect()
 | 
				
			||||||
	log.Printf("discovering services")
 | 
						log.Printf("discovering services")
 | 
				
			||||||
	runInJVM(func(env *C.JNIEnv) {
 | 
						runInJVM(func(env *C.JNIEnv) {
 | 
				
			||||||
			C.discoverServices(env, gBLE.handle.BlessedConnect, p.peripheral)
 | 
							C.discoverServices(env, gBLE.handle.BleConnect, p.gatt)
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
	}()
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//DiscoverCharacteristics asks a Peripheral for the Characteristics related
 | 
					//DiscoverCharacteristics asks a Peripheral for the Characteristics related
 | 
				
			||||||
//to a Service
 | 
					//to a Service
 | 
				
			||||||
func (p Peripheral) DiscoverCharacteristics(serv Service) {
 | 
					func (p Peripheral) DiscoverCharacteristics(serv Service) {
 | 
				
			||||||
	//launch a goroutine because this function calls back directly
 | 
						//launch a goroutine because this function calls back directly
 | 
				
			||||||
	//from the same thread (the underlying Java call is synchronous)
 | 
						//from the same thread.
 | 
				
			||||||
	go func() {
 | 
						go func() {
 | 
				
			||||||
		connect()
 | 
							connect()
 | 
				
			||||||
		log.Printf("discovering characteristics")
 | 
							log.Printf("discovering characteristics")
 | 
				
			||||||
		runInJVM(func(env *C.JNIEnv) {
 | 
							runInJVM(func(env *C.JNIEnv) {
 | 
				
			||||||
			C.discoverCharacteristics(env, gBLE.handle.BlessedConnect, p.peripheral, serv.service)
 | 
								C.discoverCharacteristics(env, gBLE.handle.BleConnect, p.gatt, serv.service)
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
 | 
							log.Printf("discovering characteristics done")
 | 
				
			||||||
	}()
 | 
						}()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//SetNotifyValue subscribes to a characteristic
 | 
					//SetNotifyValue subscribes to a characteristic
 | 
				
			||||||
func (p Peripheral) SetNotifyValue(c Characteristic) {
 | 
					func (p Peripheral) SetNotifyValue(c Characteristic) {
 | 
				
			||||||
	runInJVM(func(env *C.JNIEnv) {
 | 
						runInJVM(func(env *C.JNIEnv) {
 | 
				
			||||||
		result := (C.setCharacteristicNotification(env, gBLE.handle.BlessedConnect, p.peripheral, c.characteristic) == C.JNI_TRUE)
 | 
							log.Printf("setCharacteristicNotification: %s", c.UUID)
 | 
				
			||||||
		if (!result) {
 | 
							C.setCharacteristicNotification(env, gBLE.handle.BleConnect, p.gatt, c.characteristic)
 | 
				
			||||||
			log.Printf("setCharacteristicNotification: %s failed", c.UUID)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -225,21 +222,21 @@ func NewBLE() *BLE {
 | 
				
			||||||
//Enable
 | 
					//Enable
 | 
				
			||||||
func (b *BLE) Enable(w *app.Window) {
 | 
					func (b *BLE) Enable(w *app.Window) {
 | 
				
			||||||
	log.Printf("ble.Enable()")
 | 
						log.Printf("ble.Enable()")
 | 
				
			||||||
	w.RegisterFragment("st/wow/git/ble/BlessedConnect")
 | 
						w.RegisterFragment("st/wow/git/ble/BleConnect")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Go callbacks from Java
 | 
					// Go callbacks from Java
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//export Java_st_wow_git_ble_BlessedConnect_installComplete
 | 
					//export Java_st_wow_git_ble_BleConnect_installComplete
 | 
				
			||||||
func Java_st_wow_git_ble_BlessedConnect_installComplete(env *C.JNIEnv, class C.jclass, b C.jobject) {
 | 
					func Java_st_wow_git_ble_BleConnect_installComplete(env *C.JNIEnv, class C.jclass, b C.jobject) {
 | 
				
			||||||
	log.Printf("installComplete()")
 | 
						log.Printf("installComplete()")
 | 
				
			||||||
	if (b == 0) {
 | 
						if (b == 0) {
 | 
				
			||||||
		log.Printf("BlessedConnect object is nil!")
 | 
							log.Printf("BleConnect object is nil!")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	gBLE.handle.BlessedConnect = (C.NewGlobalRef)(env,b)
 | 
						gBLE.handle.BleConnect = (C.NewGlobalRef)(env,b)
 | 
				
			||||||
	h := app.PlatformHandle()
 | 
						h := app.PlatformHandle()
 | 
				
			||||||
	setJVM(h.JVM)
 | 
						setJVM(h.JVM)
 | 
				
			||||||
	if C.enabled(env, gBLE.handle.BlessedConnect) == C.JNI_TRUE {
 | 
						if C.enabled(env, gBLE.handle.BleConnect) == C.JNI_TRUE {
 | 
				
			||||||
		gBLE.handle.state = STATE_ON
 | 
							gBLE.handle.state = STATE_ON
 | 
				
			||||||
		gBLE.ready = true
 | 
							gBLE.ready = true
 | 
				
			||||||
		gBLE.events <- UpdateStateEvent{State: gBLE.stringState()}
 | 
							gBLE.events <- UpdateStateEvent{State: gBLE.stringState()}
 | 
				
			||||||
| 
						 | 
					@ -250,8 +247,8 @@ func Java_st_wow_git_ble_BlessedConnect_installComplete(env *C.JNIEnv, class C.j
 | 
				
			||||||
	log.Printf("installComplete() returning")
 | 
						log.Printf("installComplete() returning")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//export Java_st_wow_git_ble_BlessedConnect_updateState
 | 
					//export Java_st_wow_git_ble_BleConnect_updateState
 | 
				
			||||||
func Java_st_wow_git_ble_BlessedConnect_updateState(env *C.JNIEnv, class C.jclass, s C.jint) {
 | 
					func Java_st_wow_git_ble_BleConnect_updateState(env *C.JNIEnv, class C.jclass, s C.jint) {
 | 
				
			||||||
	log.Printf("UpdateState: %d", s)
 | 
						log.Printf("UpdateState: %d", s)
 | 
				
			||||||
	gBLE.handle.state = (int)(s)
 | 
						gBLE.handle.state = (int)(s)
 | 
				
			||||||
	if gBLE.handle.state == STATE_ON {
 | 
						if gBLE.handle.state == STATE_ON {
 | 
				
			||||||
| 
						 | 
					@ -274,7 +271,7 @@ func goOnScan(cname, cid *C.char, rssi C.int, dev C.jobject) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//export goOnConnect
 | 
					//export goOnConnect
 | 
				
			||||||
func goOnConnect(p C.jobject, cid *C.char) {
 | 
					func goOnConnect(gatt C.jobject, cid *C.char) {
 | 
				
			||||||
	id := C.GoString(cid)
 | 
						id := C.GoString(cid)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var peripheral Peripheral
 | 
						var peripheral Peripheral
 | 
				
			||||||
| 
						 | 
					@ -284,7 +281,7 @@ func goOnConnect(p C.jobject, cid *C.char) {
 | 
				
			||||||
	for n, item := range gBLE.peripherals.items {
 | 
						for n, item := range gBLE.peripherals.items {
 | 
				
			||||||
		if item.p.Identifier == id {
 | 
							if item.p.Identifier == id {
 | 
				
			||||||
			peripheral = item.p
 | 
								peripheral = item.p
 | 
				
			||||||
			peripheral.peripheral = p
 | 
								peripheral.gatt = gatt
 | 
				
			||||||
			gBLE.peripherals.items[n].p = peripheral
 | 
								gBLE.peripherals.items[n].p = peripheral
 | 
				
			||||||
			found = true
 | 
								found = true
 | 
				
			||||||
			break
 | 
								break
 | 
				
			||||||
| 
						 | 
					@ -296,8 +293,8 @@ func goOnConnect(p C.jobject, cid *C.char) {
 | 
				
			||||||
		log.Printf("Go: peripheral not found!")
 | 
							log.Printf("Go: peripheral not found!")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if peripheral.peripheral == 0 {
 | 
						if peripheral.gatt == 0 {
 | 
				
			||||||
		log.Printf("goOnConnect(): peripheral == null")
 | 
							log.Printf("goOnConnect(): gatt == null")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	gBLE.connections.UpdateState(peripheral, "connected")
 | 
						gBLE.connections.UpdateState(peripheral, "connected")
 | 
				
			||||||
| 
						 | 
					@ -384,6 +381,8 @@ func goOnDiscoverCharacteristic(cid, csuuid *C.char, serv C.jobject, ccuuid *C.c
 | 
				
			||||||
func goOnCharacteristicChanged(cid, ccuuid *C.char, char C.jobject, cvalue *C.char, length C.jint) {
 | 
					func goOnCharacteristicChanged(cid, ccuuid *C.char, char C.jobject, cvalue *C.char, length C.jint) {
 | 
				
			||||||
	id := C.GoString(cid)
 | 
						id := C.GoString(cid)
 | 
				
			||||||
	cuuid := C.GoString(ccuuid)
 | 
						cuuid := C.GoString(ccuuid)
 | 
				
			||||||
 | 
						log.Printf("goOnCharacteristicChanged: %s", cuuid)
 | 
				
			||||||
 | 
						log.Printf("goOnCharacteristicChanged: length = %d", length)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var peripheral Peripheral
 | 
						var peripheral Peripheral
 | 
				
			||||||
	found := false
 | 
						found := false
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								blessed-full.jar
									
									
									
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								blessed-full.jar
									
									
									
									
									
								
							
										
											Binary file not shown.
										
									
								
							| 
						 | 
					@ -27,43 +27,36 @@ stopScan(JNIEnv *env, jobject b) {
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
connect(JNIEnv *env, jobject b, jobject d) {
 | 
					connect(JNIEnv *env, jobject b, jobject d) {
 | 
				
			||||||
	jclass cls = (*env)->GetObjectClass(env, b);
 | 
						jclass cls = (*env)->GetObjectClass(env, b);
 | 
				
			||||||
	jmethodID mid = (*env)->GetMethodID(env, cls, "connect", "(Lcom/welie/blessed/BluetoothPeripheral;)V");
 | 
						jmethodID mid = (*env)->GetMethodID(env, cls, "connect", "(Landroid/bluetooth/BluetoothDevice;)V");
 | 
				
			||||||
	(*env)->CallObjectMethod(env, b, mid, d);
 | 
						(*env)->CallObjectMethod(env, b, mid, d);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
disconnect(JNIEnv *env, jobject b, jobject g) {
 | 
					disconnect(JNIEnv *env, jobject b, jobject g) {
 | 
				
			||||||
	jclass cls = (*env)->GetObjectClass(env, b);
 | 
						jclass cls = (*env)->GetObjectClass(env, b);
 | 
				
			||||||
	jmethodID mid = (*env)->GetMethodID(env, cls, "disconnect", "(Lcom/welie/blessed/BluetoothPeripheral;)V");
 | 
						jmethodID mid = (*env)->GetMethodID(env, cls, "disconnect", "(Landroid/bluetooth/BluetoothGatt;)V");
 | 
				
			||||||
	(*env)->CallVoidMethod(env, b, mid, g);
 | 
						(*env)->CallVoidMethod(env, b, mid, g);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
discoverServices(JNIEnv *env, jobject b, jobject p) {
 | 
					discoverServices(JNIEnv *env, jobject b, jobject p) {
 | 
				
			||||||
	jclass cls = (*env)->GetObjectClass(env, b);
 | 
						jclass cls = (*env)->GetObjectClass(env, b);
 | 
				
			||||||
	jmethodID mid = (*env)->GetMethodID(env, cls, "discoverServices", "(Lcom/welie/blessed/BluetoothPeripheral;)V");
 | 
						jmethodID mid = (*env)->GetMethodID(env, cls, "discoverServices", "(Landroid/bluetooth/BluetoothGatt;)V");
 | 
				
			||||||
	(*env)->CallVoidMethod(env, b, mid, p);
 | 
						(*env)->CallVoidMethod(env, b, mid, p);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
discoverCharacteristics(JNIEnv *env, jobject b, jobject g, jobject s) {
 | 
					discoverCharacteristics(JNIEnv *env, jobject b, jobject g, jobject s) {
 | 
				
			||||||
	jclass cls = (*env)->GetObjectClass(env, b);
 | 
						jclass cls = (*env)->GetObjectClass(env, b);
 | 
				
			||||||
	jmethodID mid = (*env)->GetMethodID(env, cls, "discoverCharacteristics", "(Lcom/welie/blessed/BluetoothPeripheral;Landroid/bluetooth/BluetoothGattService;)V");
 | 
						jmethodID mid = (*env)->GetMethodID(env, cls, "discoverCharacteristics", "(Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattService;)V");
 | 
				
			||||||
	(*env)->CallVoidMethod(env, b, mid, g, s);
 | 
						(*env)->CallVoidMethod(env, b, mid, g, s);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
jboolean
 | 
					void
 | 
				
			||||||
setCharacteristicNotification(JNIEnv *env, jobject b, jobject g, jobject c) {
 | 
					setCharacteristicNotification(JNIEnv *env, jobject b, jobject g, jobject c) {
 | 
				
			||||||
	jclass cls = (*env)->GetObjectClass(env, b);
 | 
						jclass cls = (*env)->GetObjectClass(env, b);
 | 
				
			||||||
	jmethodID mid = (*env)->GetMethodID(env, cls, "setCharacteristicNotification", "(Lcom/welie/blessed/BluetoothPeripheral;Landroid/bluetooth/BluetoothGattCharacteristic;)Z");
 | 
						jmethodID mid = (*env)->GetMethodID(env, cls, "setCharacteristicNotification", "(Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;)V");
 | 
				
			||||||
	return (*env)->CallBooleanMethod(env, b, mid, g, c);
 | 
						(*env)->CallVoidMethod(env, b, mid, g, c);
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void
 | 
					 | 
				
			||||||
readCharacteristic(JNIEnv *env, jobject b, jobject g, jobject c) {
 | 
					 | 
				
			||||||
	jclass cls = (*env)->GetObjectClass(env, b);
 | 
					 | 
				
			||||||
	jmethodID mid = (*env)->GetMethodID(env, cls, "readCharacteristic", "(Lcom/welie/blessed/BluetoothPeripheral;Landroid/bluetooth/BluetoothGattCharacteristic;)V");
 | 
					 | 
				
			||||||
	(*env)->CallBooleanMethod(env, b, mid, g, c);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
jint
 | 
					jint
 | 
				
			||||||
| 
						 | 
					@ -87,7 +80,7 @@ NewGlobalRef(JNIEnv *env, jobject o) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
Java_st_wow_git_ble_BlessedConnect_onScan(JNIEnv *env, jclass class, jstring jname, jstring jid, jint jrssi, jobject dev) {
 | 
					Java_st_wow_git_ble_BleConnect_onScan(JNIEnv *env, jclass class, jstring jname, jstring jid, jint jrssi, jobject dev) {
 | 
				
			||||||
	const char* name = (*env)->GetStringUTFChars(env, jname, NULL);
 | 
						const char* name = (*env)->GetStringUTFChars(env, jname, NULL);
 | 
				
			||||||
	const char* id = (*env)->GetStringUTFChars(env, jid, NULL);
 | 
						const char* id = (*env)->GetStringUTFChars(env, jid, NULL);
 | 
				
			||||||
	jobject gdev = (*env)->NewGlobalRef(env, dev);
 | 
						jobject gdev = (*env)->NewGlobalRef(env, dev);
 | 
				
			||||||
| 
						 | 
					@ -97,15 +90,15 @@ Java_st_wow_git_ble_BlessedConnect_onScan(JNIEnv *env, jclass class, jstring jna
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
Java_st_wow_git_ble_BlessedConnect_onConnect(JNIEnv *env, jclass class, jobject peripheral, jstring jid) {
 | 
					Java_st_wow_git_ble_BleConnect_onConnect(JNIEnv *env, jclass class, jobject gatt, jstring jid) {
 | 
				
			||||||
	const char* id = (*env)->GetStringUTFChars(env, jid, NULL);
 | 
						const char* id = (*env)->GetStringUTFChars(env, jid, NULL);
 | 
				
			||||||
	jobject gperipheral = (*env)->NewGlobalRef(env, peripheral);
 | 
						jobject ggatt = (*env)->NewGlobalRef(env, gatt);
 | 
				
			||||||
	goOnConnect(gperipheral, id);
 | 
						goOnConnect(ggatt, id);
 | 
				
			||||||
	(*env)->ReleaseStringUTFChars(env, jid, id);
 | 
						(*env)->ReleaseStringUTFChars(env, jid, id);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
Java_st_wow_git_ble_BlessedConnect_onDiscoverService(JNIEnv *env, jclass class, jstring jid, jstring juuid, jobject serv) {
 | 
					Java_st_wow_git_ble_BleConnect_onDiscoverService(JNIEnv *env, jclass class, jstring jid, jstring juuid, jobject serv) {
 | 
				
			||||||
	const char* id = (*env)->GetStringUTFChars(env, jid, NULL);
 | 
						const char* id = (*env)->GetStringUTFChars(env, jid, NULL);
 | 
				
			||||||
	const char* uuid = (*env)->GetStringUTFChars(env, juuid, NULL);
 | 
						const char* uuid = (*env)->GetStringUTFChars(env, juuid, NULL);
 | 
				
			||||||
	jobject gserv = (*env)->NewGlobalRef(env, serv);
 | 
						jobject gserv = (*env)->NewGlobalRef(env, serv);
 | 
				
			||||||
| 
						 | 
					@ -115,7 +108,7 @@ Java_st_wow_git_ble_BlessedConnect_onDiscoverService(JNIEnv *env, jclass class,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
Java_st_wow_git_ble_BlessedConnect_onDiscoverCharacteristic(JNIEnv *env, jclass class, jstring jid, jstring jsuuid, jobject serv, jstring jcuuid, jobject chr) {
 | 
					Java_st_wow_git_ble_BleConnect_onDiscoverCharacteristic(JNIEnv *env, jclass class, jstring jid, jstring jsuuid, jobject serv, jstring jcuuid, jobject chr) {
 | 
				
			||||||
	const char* id = (*env)->GetStringUTFChars(env, jid, NULL);
 | 
						const char* id = (*env)->GetStringUTFChars(env, jid, NULL);
 | 
				
			||||||
	const char* suuid = (*env)->GetStringUTFChars(env, jsuuid, NULL);
 | 
						const char* suuid = (*env)->GetStringUTFChars(env, jsuuid, NULL);
 | 
				
			||||||
	const char* cuuid = (*env)->GetStringUTFChars(env, jcuuid, NULL);
 | 
						const char* cuuid = (*env)->GetStringUTFChars(env, jcuuid, NULL);
 | 
				
			||||||
| 
						 | 
					@ -128,7 +121,7 @@ Java_st_wow_git_ble_BlessedConnect_onDiscoverCharacteristic(JNIEnv *env, jclass
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
Java_st_wow_git_ble_BlessedConnect_characteristicChanged(JNIEnv *env, jclass class, jstring jid, jstring jcuuid, jobject chr, jbyteArray jvalue, jint len) {
 | 
					Java_st_wow_git_ble_BleConnect_characteristicChanged(JNIEnv *env, jclass class, jstring jid, jstring jcuuid, jobject chr, jbyteArray jvalue, jint len) {
 | 
				
			||||||
	const char* id = (*env)->GetStringUTFChars(env, jid, NULL);
 | 
						const char* id = (*env)->GetStringUTFChars(env, jid, NULL);
 | 
				
			||||||
	const char* cuuid = (*env)->GetStringUTFChars(env, jcuuid, NULL);
 | 
						const char* cuuid = (*env)->GetStringUTFChars(env, jcuuid, NULL);
 | 
				
			||||||
	jbyte* value = (*env)->GetByteArrayElements(env, jvalue, NULL);
 | 
						jbyte* value = (*env)->GetByteArrayElements(env, jvalue, NULL);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,8 +7,7 @@ void connect(JNIEnv *env, jobject b, jobject d);
 | 
				
			||||||
void disconnect(JNIEnv *env, jobject b, jobject g);
 | 
					void disconnect(JNIEnv *env, jobject b, jobject g);
 | 
				
			||||||
void discoverServices(JNIEnv *env, jobject b, jobject p);
 | 
					void discoverServices(JNIEnv *env, jobject b, jobject p);
 | 
				
			||||||
void discoverCharacteristics(JNIEnv *env, jobject b, jobject g, jobject s);
 | 
					void discoverCharacteristics(JNIEnv *env, jobject b, jobject g, jobject s);
 | 
				
			||||||
void readCharacteristic(JNIEnv *env, jobject b, jobject g, jobject c);
 | 
					void setCharacteristicNotification(JNIEnv *env, jobject b, jobject g, jobject c);
 | 
				
			||||||
jboolean setCharacteristicNotification(JNIEnv *env, jobject b, jobject g, jobject c);
 | 
					 | 
				
			||||||
jint GetEnv(JavaVM *vm, JNIEnv **env, jint version);
 | 
					jint GetEnv(JavaVM *vm, JNIEnv **env, jint version);
 | 
				
			||||||
jint AttachCurrentThread(JavaVM *vm, JNIEnv **p_env, void *thr_args);
 | 
					jint AttachCurrentThread(JavaVM *vm, JNIEnv **p_env, void *thr_args);
 | 
				
			||||||
jint DetachCurrentThread(JavaVM *vm);
 | 
					jint DetachCurrentThread(JavaVM *vm);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								timber.jar
									
									
									
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								timber.jar
									
									
									
									
									
								
							
										
											Binary file not shown.
										
									
								
							
		Loading…
	
		Reference in New Issue
	
	Block a user