Repository: xpg/GizwitsBLE Branch: master Commit: 82300009aff2 Files: 47 Total size: 167.2 KB Directory structure: gitextract_x58tzomf/ ├── .gitignore ├── BleLibrary/ │ ├── .classpath │ ├── .project │ ├── AndroidManifest.xml │ ├── libs/ │ │ ├── com.broadcom.bt.jar │ │ ├── commons-codec-1.8.jar │ │ └── samsung_ble_sdk_200.jar │ ├── proguard-project.txt │ ├── proguard.pro │ ├── project.properties │ ├── res/ │ │ ├── values/ │ │ │ ├── strings.xml │ │ │ └── styles.xml │ │ ├── values-v11/ │ │ │ └── styles.xml │ │ └── values-v14/ │ │ └── styles.xml │ └── src/ │ └── com/ │ └── xtremeprog/ │ └── sdk/ │ └── ble/ │ ├── AndroidBle.java │ ├── BleGattCharacteristic.java │ ├── BleGattService.java │ ├── BleRequest.java │ ├── BleService.java │ ├── BroadcomBle.java │ ├── IBle.java │ ├── IBleRequestHandler.java │ └── SamsungBle.java ├── BluetoothLeGatt/ │ ├── .classpath │ ├── .project │ ├── AndroidManifest.xml │ ├── libs/ │ │ ├── com.broadcom.bt.jar │ │ ├── commons-codec-1.8.jar │ │ └── samsung_ble_sdk_200.jar │ ├── project.properties │ ├── res/ │ │ ├── layout/ │ │ │ ├── actionbar_indeterminate_progress.xml │ │ │ ├── activity_characteristic.xml │ │ │ ├── gatt_services_characteristics.xml │ │ │ └── listitem_device.xml │ │ ├── menu/ │ │ │ ├── characteristic.xml │ │ │ ├── gatt_services.xml │ │ │ └── main.xml │ │ ├── values/ │ │ │ ├── dimens.xml │ │ │ └── strings.xml │ │ └── values-w820dp/ │ │ └── dimens.xml │ └── src/ │ └── com/ │ └── example/ │ └── bluetooth/ │ └── le/ │ ├── BleApplication.java │ ├── CharacteristicActivity.java │ ├── DeviceControlActivity.java │ ├── DeviceScanActivity.java │ └── Utils.java ├── LICENSE └── README.md ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ # Built application files *.apk *.ap_ # Files for the Dalvik VM *.dex # Java class files *.class # Generated files bin/ gen/ # Gradle files .gradle/ build/ # Local configuration file (sdk path, etc) local.properties # Proguard folder generated by Eclipse proguard/ ================================================ FILE: BleLibrary/.classpath ================================================ ================================================ FILE: BleLibrary/.project ================================================ BleLibrary com.android.ide.eclipse.adt.ResourceManagerBuilder com.android.ide.eclipse.adt.PreCompilerBuilder org.eclipse.jdt.core.javabuilder com.android.ide.eclipse.adt.ApkBuilder com.android.ide.eclipse.adt.AndroidNature org.eclipse.jdt.core.javanature ================================================ FILE: BleLibrary/AndroidManifest.xml ================================================ ================================================ FILE: BleLibrary/proguard-project.txt ================================================ # To enable ProGuard in your project, edit project.properties # to define the proguard.config property as described in that file. # # Add project specific ProGuard rules here. # By default, the flags in this file are appended to flags specified # in ${sdk.dir}/tools/proguard/proguard-android.txt # You can edit the include path and order by changing the ProGuard # include property in project.properties. # # For more details, see # http://developer.android.com/guide/developing/tools/proguard.html # Add any project specific keep options here: # If your project uses WebView with JS, uncomment the following # and specify the fully qualified class name to the JavaScript interface # class: #-keepclassmembers class fqcn.of.javascript.interface.for.webview { # public *; #} ================================================ FILE: BleLibrary/proguard.pro ================================================ -injars bin/blelibrary.jar -outjars bin/blelibrary-0.1.jar -libraryjars /Users/teamx/bin/adt-bundle-mac-x86_64-20130917/sdk/platforms/android-18/android.jar -libraryjars libs/com.broadcom.bt.jar -libraryjars libs/commons-codec-1.8.jar -libraryjars libs/samsung_ble_sdk_200.jar -target 1.6 -useuniqueclassmembernames -keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,LocalVariable*Table,*Annotation*,Synthetic,EnclosingMethod -renamesourcefileattribute SourceFile -adaptresourcefilenames **.properties -adaptresourcefilecontents **.properties,META-INF/MANIFEST.MF -verbose # Keep - Library. Keep all public and protected classes, fields, and methods. -keep public class * { public protected ; public protected ; } # Also keep - Enumerations. Keep the special static methods that are required in # enumeration classes. -keepclassmembers enum * { public static **[] values(); public static ** valueOf(java.lang.String); } # Keep names - Native method names. Keep all native class/method names. -keepclasseswithmembers,allowshrinking class * { native ; } ================================================ FILE: BleLibrary/project.properties ================================================ # This file is automatically generated by Android Tools. # Do not modify this file -- YOUR CHANGES WILL BE ERASED! # # This file must be checked in Version Control Systems. # # To customize properties used by the Ant build system edit # "ant.properties", and override values to adapt the script to your # project structure. # # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt # Project target. target=android-19 android.library=true ================================================ FILE: BleLibrary/res/values/strings.xml ================================================ BleLibrary ================================================ FILE: BleLibrary/res/values/styles.xml ================================================ ================================================ FILE: BleLibrary/res/values-v11/styles.xml ================================================ ================================================ FILE: BleLibrary/res/values-v14/styles.xml ================================================ ================================================ FILE: BleLibrary/src/com/xtremeprog/sdk/ble/AndroidBle.java ================================================ /** * This XPG software is supplied to you by Xtreme Programming Group, Inc. * ("XPG") in consideration of your agreement to the following terms, and your * use, installation, modification or redistribution of this XPG software * constitutes acceptance of these terms.� If you do not agree with these terms, * please do not use, install, modify or redistribute this XPG software. * * In consideration of your agreement to abide by the following terms, and * subject to these terms, XPG grants you a non-exclusive license, under XPG's * copyrights in this original XPG software (the "XPG Software"), to use and * redistribute the XPG Software, in source and/or binary forms; provided that * if you redistribute the XPG Software, with or without modifications, you must * retain this notice and the following text and disclaimers in all such * redistributions of the XPG Software. Neither the name, trademarks, service * marks or logos of XPG Inc. may be used to endorse or promote products derived * from the XPG Software without specific prior written permission from XPG.� * Except as expressly stated in this notice, no other rights or licenses, * express or implied, are granted by XPG herein, including but not limited to * any patent rights that may be infringed by your derivative works or by other * works in which the XPG Software may be incorporated. * * The XPG Software is provided by XPG on an "AS IS" basis.� XPG MAKES NO * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE, REGARDING THE XPG SOFTWARE OR ITS USE AND OPERATION ALONE OR IN * COMBINATION WITH YOUR PRODUCTS. * * IN NO EVENT SHALL XPG BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION * AND/OR DISTRIBUTION OF THE XPG SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER * THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR * OTHERWISE, EVEN IF XPG HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ABOUT XPG: Established since June 2005, Xtreme Programming Group, Inc. (XPG) * is a digital solutions company based in the United States and China. XPG * integrates cutting-edge hardware designs, mobile applications, and cloud * computing technologies to bring innovative products to the marketplace. XPG's * partners and customers include global leading corporations in semiconductor, * home appliances, health/wellness electronics, toys and games, and automotive * industries. Visit www.xtremeprog.com for more information. * * Copyright (C) 2013 Xtreme Programming Group, Inc. All Rights Reserved. */ package com.xtremeprog.sdk.ble; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; import org.apache.commons.codec.binary.Hex; import android.annotation.SuppressLint; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothGatt; import android.bluetooth.BluetoothGattCallback; import android.bluetooth.BluetoothGattCharacteristic; import android.bluetooth.BluetoothGattDescriptor; import android.bluetooth.BluetoothGattService; import android.bluetooth.BluetoothManager; import android.bluetooth.BluetoothProfile; import android.content.Context; import android.content.pm.PackageManager; import android.util.Log; import com.xtremeprog.sdk.ble.BleRequest.RequestType; @SuppressLint("NewApi") public class AndroidBle implements IBle, IBleRequestHandler { protected static final String TAG = "blelib"; private BleService mService; private BluetoothAdapter mBtAdapter; private Map mBluetoothGatts; // private BTQuery btQuery; private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() { @Override public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) { mService.bleDeviceFound(device, rssi, scanRecord, BleService.DEVICE_SOURCE_SCAN); } }; private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { @Override public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { String address = gatt.getDevice().getAddress(); Log.d(TAG, "onConnectionStateChange " + address + " status " + status + " newState " + newState); if (status != BluetoothGatt.GATT_SUCCESS) { disconnect(address); mService.bleGattDisConnected(address); return; } if (newState == BluetoothProfile.STATE_CONNECTED) { mService.bleGattConnected(gatt.getDevice()); mService.addBleRequest(new BleRequest( RequestType.DISCOVER_SERVICE, address)); } else if (newState == BluetoothProfile.STATE_DISCONNECTED) { mService.bleGattDisConnected(address); disconnect(address); } } @Override public void onServicesDiscovered(BluetoothGatt gatt, int status) { String address = gatt.getDevice().getAddress(); Log.d(TAG, "onServicesDiscovered " + address + " status " + status); if (status != BluetoothGatt.GATT_SUCCESS) { mService.requestProcessed(address, RequestType.DISCOVER_SERVICE, false); return; } mService.bleServiceDiscovered(gatt.getDevice().getAddress()); } @Override public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { String address = gatt.getDevice().getAddress(); Log.d(TAG, "onCharacteristicRead " + address + " status " + status); if (status != BluetoothGatt.GATT_SUCCESS) { mService.requestProcessed(address, RequestType.READ_CHARACTERISTIC, false); return; } // Log.d(TAG, "data " + characteristic.getStringValue(0)); mService.bleCharacteristicRead(gatt.getDevice().getAddress(), characteristic.getUuid().toString(), status, characteristic.getValue()); } @Override public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) { String address = gatt.getDevice().getAddress(); Log.d(TAG, "onCharacteristicChanged " + address); Log.d(TAG, new String(Hex.encodeHex(characteristic.getValue()))); mService.bleCharacteristicChanged(address, characteristic.getUuid() .toString(), characteristic.getValue()); } public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { String address = gatt.getDevice().getAddress(); Log.d(TAG, "onCharacteristicWrite " + address + " status " + status); if (status != BluetoothGatt.GATT_SUCCESS) { mService.requestProcessed(address, RequestType.WRITE_CHARACTERISTIC, false); return; } mService.bleCharacteristicWrite(gatt.getDevice().getAddress(), characteristic.getUuid().toString(), status); }; public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) { String address = gatt.getDevice().getAddress(); Log.d(TAG, "onDescriptorWrite " + address + " status " + status); BleRequest request = mService.getCurrentRequest(); if (request.type == RequestType.CHARACTERISTIC_NOTIFICATION || request.type == RequestType.CHARACTERISTIC_INDICATION || request.type == RequestType.CHARACTERISTIC_STOP_NOTIFICATION) { if (status != BluetoothGatt.GATT_SUCCESS) { mService.requestProcessed(address, RequestType.CHARACTERISTIC_NOTIFICATION, false); return; } if (request.type == RequestType.CHARACTERISTIC_NOTIFICATION) { mService.bleCharacteristicNotification(address, descriptor .getCharacteristic().getUuid().toString(), true, status); } else if (request.type == RequestType.CHARACTERISTIC_INDICATION) { mService.bleCharacteristicIndication(address, descriptor .getCharacteristic().getUuid().toString(), status); } else { mService.bleCharacteristicNotification(address, descriptor .getCharacteristic().getUuid().toString(), false, status); } return; } }; }; public AndroidBle(BleService service) { mService = service; // btQuery = BTQuery.getInstance(); if (!mService.getPackageManager().hasSystemFeature( PackageManager.FEATURE_BLUETOOTH_LE)) { mService.bleNotSupported(); return; } final BluetoothManager bluetoothManager = (BluetoothManager) mService .getSystemService(Context.BLUETOOTH_SERVICE); mBtAdapter = bluetoothManager.getAdapter(); if (mBtAdapter == null) { mService.bleNoBtAdapter(); } mBluetoothGatts = new HashMap(); } @Override public void startScan() { mBtAdapter.startLeScan(mLeScanCallback); } @Override public void stopScan() { mBtAdapter.stopLeScan(mLeScanCallback); } @Override public boolean adapterEnabled() { if (mBtAdapter != null) { return mBtAdapter.isEnabled(); } return false; } @Override public boolean connect(String address) { BluetoothDevice device = mBtAdapter.getRemoteDevice(address); BluetoothGatt gatt = device.connectGatt(mService, false, mGattCallback); if (gatt == null) { mBluetoothGatts.remove(address); return false; } else { // TODO: if state is 141, it can be connected again after about 15 // seconds mBluetoothGatts.put(address, gatt); return true; } } @Override public void disconnect(String address) { if (mBluetoothGatts.containsKey(address)) { BluetoothGatt gatt = mBluetoothGatts.remove(address); if (gatt != null) { gatt.disconnect(); gatt.close(); } } } @Override public ArrayList getServices(String address) { BluetoothGatt gatt = mBluetoothGatts.get(address); if (gatt == null) { return null; } ArrayList list = new ArrayList(); List services = gatt.getServices(); for (BluetoothGattService s : services) { BleGattService service = new BleGattService(s); // service.setInfo(btQuery.getGattServiceInfo(s.getUuid())); list.add(service); } return list; } @Override public boolean requestReadCharacteristic(String address, BleGattCharacteristic characteristic) { BluetoothGatt gatt = mBluetoothGatts.get(address); if (gatt == null || characteristic == null) { return false; } mService.addBleRequest(new BleRequest(RequestType.READ_CHARACTERISTIC, gatt.getDevice().getAddress(), characteristic)); return true; } public boolean readCharacteristic(String address, BleGattCharacteristic characteristic) { BluetoothGatt gatt = mBluetoothGatts.get(address); if (gatt == null) { return false; } return gatt.readCharacteristic(characteristic.getGattCharacteristicA()); } @Override public boolean discoverServices(String address) { BluetoothGatt gatt = mBluetoothGatts.get(address); if (gatt == null) { return false; } boolean ret = gatt.discoverServices(); if (!ret) { disconnect(address); } return ret; } @Override public BleGattService getService(String address, UUID uuid) { BluetoothGatt gatt = mBluetoothGatts.get(address); if (gatt == null) { return null; } BluetoothGattService service = gatt.getService(uuid); if (service == null) { return null; } else { return new BleGattService(service); } } @Override public boolean requestCharacteristicNotification(String address, BleGattCharacteristic characteristic) { BluetoothGatt gatt = mBluetoothGatts.get(address); if (gatt == null || characteristic == null) { return false; } mService.addBleRequest(new BleRequest( RequestType.CHARACTERISTIC_NOTIFICATION, gatt.getDevice() .getAddress(), characteristic)); return true; } @Override public boolean characteristicNotification(String address, BleGattCharacteristic characteristic) { BleRequest request = mService.getCurrentRequest(); BluetoothGatt gatt = mBluetoothGatts.get(address); if (gatt == null || characteristic == null) { return false; } boolean enable = true; if (request.type == RequestType.CHARACTERISTIC_STOP_NOTIFICATION) { enable = false; } BluetoothGattCharacteristic c = characteristic.getGattCharacteristicA(); if (!gatt.setCharacteristicNotification(c, enable)) { return false; } BluetoothGattDescriptor descriptor = c .getDescriptor(BleService.DESC_CCC); if (descriptor == null) { return false; } byte[] val_set = null; if (request.type == RequestType.CHARACTERISTIC_NOTIFICATION) { val_set = BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE; } else if (request.type == RequestType.CHARACTERISTIC_INDICATION) { val_set = BluetoothGattDescriptor.ENABLE_INDICATION_VALUE; } else { val_set = BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE; } if (!descriptor.setValue(val_set)) { return false; } return gatt.writeDescriptor(descriptor); } @Override public boolean requestWriteCharacteristic(String address, BleGattCharacteristic characteristic, String remark) { BluetoothGatt gatt = mBluetoothGatts.get(address); if (gatt == null || characteristic == null) { return false; } mService.addBleRequest(new BleRequest(RequestType.WRITE_CHARACTERISTIC, gatt.getDevice().getAddress(), characteristic, remark)); return true; } @Override public boolean writeCharacteristic(String address, BleGattCharacteristic characteristic) { BluetoothGatt gatt = mBluetoothGatts.get(address); if (gatt == null) { return false; } Log.d("blelib", new String(Hex.encodeHex(characteristic.getGattCharacteristicA().getValue()))); return gatt .writeCharacteristic(characteristic.getGattCharacteristicA()); } @Override public boolean requestConnect(String address) { BluetoothGatt gatt = mBluetoothGatts.get(address); if (gatt != null && gatt.getServices().size() == 0) { return false; } mService.addBleRequest(new BleRequest(RequestType.CONNECT_GATT, address)); return true; } @Override public String getBTAdapterMacAddr() { if (mBtAdapter != null) { return mBtAdapter.getAddress(); } return null; } @Override public boolean requestIndication(String address, BleGattCharacteristic characteristic) { BluetoothGatt gatt = mBluetoothGatts.get(address); if (gatt == null || characteristic == null) { return false; } mService.addBleRequest(new BleRequest( RequestType.CHARACTERISTIC_INDICATION, gatt.getDevice() .getAddress(), characteristic)); return true; } @Override public boolean requestStopNotification(String address, BleGattCharacteristic characteristic) { BluetoothGatt gatt = mBluetoothGatts.get(address); if (gatt == null || characteristic == null) { return false; } mService.addBleRequest(new BleRequest( RequestType.CHARACTERISTIC_NOTIFICATION, gatt.getDevice() .getAddress(), characteristic)); return true; } } ================================================ FILE: BleLibrary/src/com/xtremeprog/sdk/ble/BleGattCharacteristic.java ================================================ /** * This XPG software is supplied to you by Xtreme Programming Group, Inc. * ("XPG") in consideration of your agreement to the following terms, and your * use, installation, modification or redistribution of this XPG software * constitutes acceptance of these terms.� If you do not agree with these terms, * please do not use, install, modify or redistribute this XPG software. * * In consideration of your agreement to abide by the following terms, and * subject to these terms, XPG grants you a non-exclusive license, under XPG's * copyrights in this original XPG software (the "XPG Software"), to use and * redistribute the XPG Software, in source and/or binary forms; provided that * if you redistribute the XPG Software, with or without modifications, you must * retain this notice and the following text and disclaimers in all such * redistributions of the XPG Software. Neither the name, trademarks, service * marks or logos of XPG Inc. may be used to endorse or promote products derived * from the XPG Software without specific prior written permission from XPG.� * Except as expressly stated in this notice, no other rights or licenses, * express or implied, are granted by XPG herein, including but not limited to * any patent rights that may be infringed by your derivative works or by other * works in which the XPG Software may be incorporated. * * The XPG Software is provided by XPG on an "AS IS" basis.� XPG MAKES NO * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE, REGARDING THE XPG SOFTWARE OR ITS USE AND OPERATION ALONE OR IN * COMBINATION WITH YOUR PRODUCTS. * * IN NO EVENT SHALL XPG BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION * AND/OR DISTRIBUTION OF THE XPG SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER * THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR * OTHERWISE, EVEN IF XPG HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ABOUT XPG: Established since June 2005, Xtreme Programming Group, Inc. (XPG) * is a digital solutions company based in the United States and China. XPG * integrates cutting-edge hardware designs, mobile applications, and cloud * computing technologies to bring innovative products to the marketplace. XPG's * partners and customers include global leading corporations in semiconductor, * home appliances, health/wellness electronics, toys and games, and automotive * industries. Visit www.xtremeprog.com for more information. * * Copyright (C) 2013 Xtreme Programming Group, Inc. All Rights Reserved. */ package com.xtremeprog.sdk.ble; import java.util.UUID; import android.annotation.SuppressLint; import com.xtremeprog.sdk.ble.BleService.BLESDK; @SuppressLint("NewApi") public class BleGattCharacteristic { public static final int PROPERTY_READ = 2; public static final int PROPERTY_WRITE = 8; public static final int PROPERTY_NOTIFY = 16; public static final int PROPERTY_INDICATE = 32; /** * Characteristic value format type uint8 */ public static final int FORMAT_UINT8 = 0x11; /** * Characteristic value format type uint16 */ public static final int FORMAT_UINT16 = 0x12; /** * Characteristic value format type uint24 Note: this is not a standard data * type! */ public static final int FORMAT_UINT24 = 0x13; /** * Characteristic value format type uint32 */ public static final int FORMAT_UINT32 = 0x14; /** * Characteristic value format type sint8 */ public static final int FORMAT_SINT8 = 0x21; /** * Characteristic value format type sint16 */ public static final int FORMAT_SINT16 = 0x22; /** * Characteristic value format type sint32 */ public static final int FORMAT_SINT32 = 0x24; /** * Characteristic value format type sfloat (16-bit float) */ public static final int FORMAT_SFLOAT = 0x32; /** * Characteristic value format type float (32-bit float) */ public static final int FORMAT_FLOAT = 0x34; private android.bluetooth.BluetoothGattCharacteristic mGattCharacteristicA; private com.broadcom.bt.gatt.BluetoothGattCharacteristic mGattCharacteristicB; private com.samsung.android.sdk.bt.gatt.BluetoothGattCharacteristic mGattCharacteristicS; private BLESDK mBleSDK; private String name; public BleGattCharacteristic(android.bluetooth.BluetoothGattCharacteristic c) { mBleSDK = BLESDK.ANDROID; setGattCharacteristicA(c); initInfo(); } public BleGattCharacteristic( com.broadcom.bt.gatt.BluetoothGattCharacteristic c) { mBleSDK = BLESDK.BROADCOM; setGattCharacteristicB(c); } public BleGattCharacteristic( com.samsung.android.sdk.bt.gatt.BluetoothGattCharacteristic c) { mBleSDK = BLESDK.SAMSUNG; setGattCharacteristicS(c); } private void initInfo() { name = "Unknown characteristic"; } public UUID getUuid() { if (mBleSDK == BLESDK.ANDROID) { return getGattCharacteristicA().getUuid(); } else if (mBleSDK == BLESDK.BROADCOM) { return getGattCharacteristicB().getUuid(); } else if (mBleSDK == BLESDK.SAMSUNG) { return getGattCharacteristicS().getUuid(); } return null; } protected android.bluetooth.BluetoothGattCharacteristic getGattCharacteristicA() { return mGattCharacteristicA; } public int getProperties() { if (mBleSDK == BLESDK.ANDROID) { return getGattCharacteristicA().getProperties(); } else if (mBleSDK == BLESDK.BROADCOM) { return getGattCharacteristicB().getProperties(); } else if (mBleSDK == BLESDK.SAMSUNG) { return getGattCharacteristicS().getProperties(); } return 0; } protected com.broadcom.bt.gatt.BluetoothGattCharacteristic getGattCharacteristicB() { return mGattCharacteristicB; } protected void setGattCharacteristicB( com.broadcom.bt.gatt.BluetoothGattCharacteristic mBCGattCharacteristic) { this.mGattCharacteristicB = mBCGattCharacteristic; } public String getName() { return name; } public void setName(String name) { this.name = name; } public boolean setValue(byte[] val) { if (mBleSDK == BLESDK.ANDROID) { return getGattCharacteristicA().setValue(val); } else if (mBleSDK == BLESDK.SAMSUNG) { return mGattCharacteristicS.setValue(val); } else if (mBleSDK == BLESDK.BROADCOM) { return mGattCharacteristicB.setValue(val); } return false; } public byte[] getValue() { if (mBleSDK == BLESDK.ANDROID) { return getGattCharacteristicA().getValue(); } else if (mBleSDK == BLESDK.SAMSUNG) { return mGattCharacteristicS.getValue(); } else if (mBleSDK == BLESDK.BROADCOM) { return mGattCharacteristicB.getValue(); } return null; } public boolean setValue(int value, int formatType, int offset) { if (mBleSDK == BLESDK.ANDROID) { return getGattCharacteristicA().setValue(value, formatType, offset); } else if (mBleSDK == BLESDK.SAMSUNG) { return mGattCharacteristicS.setValue(value, formatType, offset); } else if (mBleSDK == BLESDK.BROADCOM) { return mGattCharacteristicB.setValue(value, formatType, offset); } return false; } public boolean setValue(int mantissa, int exponent, int formatType, int offset) { if (mBleSDK == BLESDK.ANDROID) { return getGattCharacteristicA().setValue(mantissa, exponent, formatType, offset); } else if (mBleSDK == BLESDK.SAMSUNG) { return mGattCharacteristicS.setValue(mantissa, exponent, formatType, offset); } else if (mBleSDK == BLESDK.BROADCOM) { return mGattCharacteristicB.setValue(mantissa, exponent, formatType, offset); } return false; } public boolean setValue(String value) { return setValue(value.getBytes()); } public String getStringValue(int offset) { if (mBleSDK == BLESDK.ANDROID) { return getGattCharacteristicA().getStringValue(offset); } else if (mBleSDK == BLESDK.SAMSUNG) { return mGattCharacteristicS.getStringValue(offset); } else if (mBleSDK == BLESDK.BROADCOM) { return mGattCharacteristicB.getStringValue(offset); } return null; } public Float getFloatValue(int formatType, int offset) { if (mBleSDK == BLESDK.ANDROID) { return getGattCharacteristicA().getFloatValue(formatType, offset); } else if (mBleSDK == BLESDK.SAMSUNG) { return mGattCharacteristicS.getFloatValue(formatType, offset); } else if (mBleSDK == BLESDK.BROADCOM) { return mGattCharacteristicB.getFloatValue(formatType, offset); } return null; } public Integer getIntValue(int formatType, int offset) { if (mBleSDK == BLESDK.ANDROID) { if (formatType == FORMAT_UINT24) { byte[] value = getGattCharacteristicA().getValue(); return byte2uint24(offset, value); } else { return getGattCharacteristicA().getIntValue(formatType, offset); } } else if (mBleSDK == BLESDK.SAMSUNG) { if (formatType == FORMAT_UINT24) { byte[] value = mGattCharacteristicS.getValue(); return byte2uint24(offset, value); } else { return mGattCharacteristicS.getIntValue(formatType, offset); } } else if (mBleSDK == BLESDK.BROADCOM) { if (formatType == FORMAT_UINT24) { byte[] value = mGattCharacteristicB.getValue(); return byte2uint24(offset, value); } else { return mGattCharacteristicB.getIntValue(formatType, offset); } } return null; } private Integer byte2uint24(int offset, byte[] value) { if ((offset + 3) > value.length) return null; return Integer.valueOf((value[offset] & 0xFF) | (value[offset + 1] & 0xFF) << 8 | (value[offset + 2] & 0xFF) << 16); } protected com.samsung.android.sdk.bt.gatt.BluetoothGattCharacteristic getGattCharacteristicS() { return mGattCharacteristicS; } protected void setGattCharacteristicS( com.samsung.android.sdk.bt.gatt.BluetoothGattCharacteristic mSSGattCharacteristic) { this.mGattCharacteristicS = mSSGattCharacteristic; } protected void setGattCharacteristicA( android.bluetooth.BluetoothGattCharacteristic mGattCharacteristicA) { this.mGattCharacteristicA = mGattCharacteristicA; } } ================================================ FILE: BleLibrary/src/com/xtremeprog/sdk/ble/BleGattService.java ================================================ /** * This XPG software is supplied to you by Xtreme Programming Group, Inc. * ("XPG") in consideration of your agreement to the following terms, and your * use, installation, modification or redistribution of this XPG software * constitutes acceptance of these terms.� If you do not agree with these terms, * please do not use, install, modify or redistribute this XPG software. * * In consideration of your agreement to abide by the following terms, and * subject to these terms, XPG grants you a non-exclusive license, under XPG's * copyrights in this original XPG software (the "XPG Software"), to use and * redistribute the XPG Software, in source and/or binary forms; provided that * if you redistribute the XPG Software, with or without modifications, you must * retain this notice and the following text and disclaimers in all such * redistributions of the XPG Software. Neither the name, trademarks, service * marks or logos of XPG Inc. may be used to endorse or promote products derived * from the XPG Software without specific prior written permission from XPG.� * Except as expressly stated in this notice, no other rights or licenses, * express or implied, are granted by XPG herein, including but not limited to * any patent rights that may be infringed by your derivative works or by other * works in which the XPG Software may be incorporated. * * The XPG Software is provided by XPG on an "AS IS" basis.� XPG MAKES NO * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE, REGARDING THE XPG SOFTWARE OR ITS USE AND OPERATION ALONE OR IN * COMBINATION WITH YOUR PRODUCTS. * * IN NO EVENT SHALL XPG BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION * AND/OR DISTRIBUTION OF THE XPG SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER * THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR * OTHERWISE, EVEN IF XPG HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ABOUT XPG: Established since June 2005, Xtreme Programming Group, Inc. (XPG) * is a digital solutions company based in the United States and China. XPG * integrates cutting-edge hardware designs, mobile applications, and cloud * computing technologies to bring innovative products to the marketplace. XPG's * partners and customers include global leading corporations in semiconductor, * home appliances, health/wellness electronics, toys and games, and automotive * industries. Visit www.xtremeprog.com for more information. * * Copyright (C) 2013 Xtreme Programming Group, Inc. All Rights Reserved. */ package com.xtremeprog.sdk.ble; import java.util.ArrayList; import java.util.List; import java.util.UUID; import org.json.JSONException; import org.json.JSONObject; import android.annotation.SuppressLint; import android.bluetooth.BluetoothGattCharacteristic; import com.xtremeprog.sdk.ble.BleService.BLESDK; @SuppressLint("NewApi") public class BleGattService { private BLESDK mBleSDK; private com.samsung.android.sdk.bt.gatt.BluetoothGattService mGattServiceS; private com.broadcom.bt.gatt.BluetoothGattService mGattServiceB; private android.bluetooth.BluetoothGattService mGattServiceA; private String mName; public BleGattService(com.samsung.android.sdk.bt.gatt.BluetoothGattService s) { mBleSDK = BLESDK.SAMSUNG; mGattServiceS = s; initInfo(); } public BleGattService(com.broadcom.bt.gatt.BluetoothGattService s) { mBleSDK = BLESDK.BROADCOM; mGattServiceB = s; initInfo(); } public BleGattService(android.bluetooth.BluetoothGattService s) { mBleSDK = BLESDK.ANDROID; mGattServiceA = s; initInfo(); } private void initInfo() { mName = "Unknown Service"; } public UUID getUuid() { if (mBleSDK == BLESDK.BROADCOM) { return mGattServiceB.getUuid(); } else if (mBleSDK == BLESDK.SAMSUNG) { return mGattServiceS.getUuid(); } else if (mBleSDK == BLESDK.ANDROID) { return mGattServiceA.getUuid(); } return null; } public List getCharacteristics() { ArrayList list = new ArrayList(); if (mBleSDK == BLESDK.BROADCOM) { for (com.broadcom.bt.gatt.BluetoothGattCharacteristic c : mGattServiceB .getCharacteristics()) { list.add(new BleGattCharacteristic(c)); } } else if (mBleSDK == BLESDK.SAMSUNG) { for (Object o : mGattServiceS.getCharacteristics()) { com.samsung.android.sdk.bt.gatt.BluetoothGattCharacteristic c = (com.samsung.android.sdk.bt.gatt.BluetoothGattCharacteristic) o; list.add(new BleGattCharacteristic(c)); } } else if (mBleSDK == BLESDK.ANDROID) { for (android.bluetooth.BluetoothGattCharacteristic c : mGattServiceA .getCharacteristics()) { list.add(new BleGattCharacteristic(c)); } } return list; } public BleGattCharacteristic getCharacteristic(UUID uuid) { if (mBleSDK == BLESDK.ANDROID) { BluetoothGattCharacteristic c = mGattServiceA .getCharacteristic(uuid); if (c != null) { return new BleGattCharacteristic(c); } } else if (mBleSDK == BLESDK.SAMSUNG) { com.samsung.android.sdk.bt.gatt.BluetoothGattCharacteristic c = mGattServiceS .getCharacteristic(uuid); if (c != null) { return new BleGattCharacteristic(c); } } else if (mBleSDK == BLESDK.BROADCOM) { com.broadcom.bt.gatt.BluetoothGattCharacteristic c = mGattServiceB .getCharacteristic(uuid); if (c != null) { return new BleGattCharacteristic(c); } } return null; } public void setInfo(JSONObject info) { if (info == null) { return; } try { setName(info.getString("name")); } catch (JSONException e) { e.printStackTrace(); } } public String getName() { return mName; } public void setName(String mName) { this.mName = mName; } } ================================================ FILE: BleLibrary/src/com/xtremeprog/sdk/ble/BleRequest.java ================================================ /** * This XPG software is supplied to you by Xtreme Programming Group, Inc. * ("XPG") in consideration of your agreement to the following terms, and your * use, installation, modification or redistribution of this XPG software * constitutes acceptance of these terms.� If you do not agree with these terms, * please do not use, install, modify or redistribute this XPG software. * * In consideration of your agreement to abide by the following terms, and * subject to these terms, XPG grants you a non-exclusive license, under XPG's * copyrights in this original XPG software (the "XPG Software"), to use and * redistribute the XPG Software, in source and/or binary forms; provided that * if you redistribute the XPG Software, with or without modifications, you must * retain this notice and the following text and disclaimers in all such * redistributions of the XPG Software. Neither the name, trademarks, service * marks or logos of XPG Inc. may be used to endorse or promote products derived * from the XPG Software without specific prior written permission from XPG.� * Except as expressly stated in this notice, no other rights or licenses, * express or implied, are granted by XPG herein, including but not limited to * any patent rights that may be infringed by your derivative works or by other * works in which the XPG Software may be incorporated. * * The XPG Software is provided by XPG on an "AS IS" basis.� XPG MAKES NO * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE, REGARDING THE XPG SOFTWARE OR ITS USE AND OPERATION ALONE OR IN * COMBINATION WITH YOUR PRODUCTS. * * IN NO EVENT SHALL XPG BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION * AND/OR DISTRIBUTION OF THE XPG SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER * THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR * OTHERWISE, EVEN IF XPG HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ABOUT XPG: Established since June 2005, Xtreme Programming Group, Inc. (XPG) * is a digital solutions company based in the United States and China. XPG * integrates cutting-edge hardware designs, mobile applications, and cloud * computing technologies to bring innovative products to the marketplace. XPG's * partners and customers include global leading corporations in semiconductor, * home appliances, health/wellness electronics, toys and games, and automotive * industries. Visit www.xtremeprog.com for more information. * * Copyright (C) 2013 Xtreme Programming Group, Inc. All Rights Reserved. */ package com.xtremeprog.sdk.ble; public class BleRequest { public enum RequestType { CONNECT_GATT, DISCOVER_SERVICE, CHARACTERISTIC_NOTIFICATION, CHARACTERISTIC_INDICATION, READ_CHARACTERISTIC, READ_DESCRIPTOR, READ_RSSI, WRITE_CHARACTERISTIC, WRITE_DESCRIPTOR, CHARACTERISTIC_STOP_NOTIFICATION }; public enum FailReason { START_FAILED, TIMEOUT, RESULT_FAILED } public RequestType type; public String address; public BleGattCharacteristic characteristic; public String remark; public BleRequest(RequestType type, String address) { this.type = type; this.address = address; } public BleRequest(RequestType type, String address, BleGattCharacteristic characteristic) { this.type = type; this.address = address; this.characteristic = characteristic; } public BleRequest(RequestType type, String address, BleGattCharacteristic characteristic, String remark) { this.type = type; this.address = address; this.characteristic = characteristic; this.remark = remark; } @Override public boolean equals(Object o) { if (!(o instanceof BleRequest)) { return false; } BleRequest br = (BleRequest) o; return (this.type == br.type && this.address.equals(br.address)); } } ================================================ FILE: BleLibrary/src/com/xtremeprog/sdk/ble/BleService.java ================================================ /** * This XPG software is supplied to you by Xtreme Programming Group, Inc. * ("XPG") in consideration of your agreement to the following terms, and your * use, installation, modification or redistribution of this XPG software * constitutes acceptance of these terms.� If you do not agree with these terms, * please do not use, install, modify or redistribute this XPG software. * * In consideration of your agreement to abide by the following terms, and * subject to these terms, XPG grants you a non-exclusive license, under XPG's * copyrights in this original XPG software (the "XPG Software"), to use and * redistribute the XPG Software, in source and/or binary forms; provided that * if you redistribute the XPG Software, with or without modifications, you must * retain this notice and the following text and disclaimers in all such * redistributions of the XPG Software. Neither the name, trademarks, service * marks or logos of XPG Inc. may be used to endorse or promote products derived * from the XPG Software without specific prior written permission from XPG.� * Except as expressly stated in this notice, no other rights or licenses, * express or implied, are granted by XPG herein, including but not limited to * any patent rights that may be infringed by your derivative works or by other * works in which the XPG Software may be incorporated. * * The XPG Software is provided by XPG on an "AS IS" basis.� XPG MAKES NO * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE, REGARDING THE XPG SOFTWARE OR ITS USE AND OPERATION ALONE OR IN * COMBINATION WITH YOUR PRODUCTS. * * IN NO EVENT SHALL XPG BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION * AND/OR DISTRIBUTION OF THE XPG SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER * THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR * OTHERWISE, EVEN IF XPG HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ABOUT XPG: Established since June 2005, Xtreme Programming Group, Inc. (XPG) * is a digital solutions company based in the United States and China. XPG * integrates cutting-edge hardware designs, mobile applications, and cloud * computing technologies to bring innovative products to the marketplace. XPG's * partners and customers include global leading corporations in semiconductor, * home appliances, health/wellness electronics, toys and games, and automotive * industries. Visit www.xtremeprog.com for more information. * * Copyright (C) 2013 Xtreme Programming Group, Inc. All Rights Reserved. */ package com.xtremeprog.sdk.ble; import java.util.ArrayList; import java.util.Date; import java.util.LinkedList; import java.util.Queue; import java.util.UUID; import android.app.Service; import android.bluetooth.BluetoothDevice; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; import android.os.Binder; import android.os.IBinder; import android.util.Log; import com.xtremeprog.sdk.ble.BleRequest.FailReason; import com.xtremeprog.sdk.ble.BleRequest.RequestType; public class BleService extends Service { private static final String TAG = "blelib"; /** Intent for broadcast */ public static final String BLE_NOT_SUPPORTED = "com.xtremeprog.sdk.ble.not_supported"; public static final String BLE_NO_BT_ADAPTER = "com.xtremeprog.sdk.ble.no_bt_adapter"; public static final String BLE_STATUS_ABNORMAL = "com.xtremeprog.sdk.ble.status_abnormal"; /** * @see BleService#bleRequestFailed */ public static final String BLE_REQUEST_FAILED = "com.xtremeprog.sdk.ble.request_failed"; /** * @see BleService#bleDeviceFound */ public static final String BLE_DEVICE_FOUND = "com.xtremeprog.sdk.ble.device_found"; /** * @see BleService#bleGattConnected */ public static final String BLE_GATT_CONNECTED = "com.xtremeprog.sdk.ble.gatt_connected"; /** * @see BleService#bleGattDisConnected */ public static final String BLE_GATT_DISCONNECTED = "com.xtremeprog.sdk.ble.gatt_disconnected"; /** * @see BleService#bleServiceDiscovered */ public static final String BLE_SERVICE_DISCOVERED = "com.xtremeprog.sdk.ble.service_discovered"; /** * @see BleService#bleCharacteristicRead */ public static final String BLE_CHARACTERISTIC_READ = "com.xtremeprog.sdk.ble.characteristic_read"; /** * @see BleService#bleCharacteristicNotification */ public static final String BLE_CHARACTERISTIC_NOTIFICATION = "com.xtremeprog.sdk.ble.characteristic_notification"; /** * @see BleService#bleCharacteristicIndication */ public static final String BLE_CHARACTERISTIC_INDICATION = "com.xtremeprog.sdk.ble.characteristic_indication"; /** * @see BleService#bleCharacteristicWrite */ public static final String BLE_CHARACTERISTIC_WRITE = "com.xtremeprog.sdk.ble.characteristic_write"; /** * @see BleService#bleCharacteristicChanged */ public static final String BLE_CHARACTERISTIC_CHANGED = "com.xtremeprog.sdk.ble.characteristic_changed"; /** Intent extras */ public static final String EXTRA_DEVICE = "DEVICE"; public static final String EXTRA_RSSI = "RSSI"; public static final String EXTRA_SCAN_RECORD = "SCAN_RECORD"; public static final String EXTRA_SOURCE = "SOURCE"; public static final String EXTRA_ADDR = "ADDRESS"; public static final String EXTRA_CONNECTED = "CONNECTED"; public static final String EXTRA_STATUS = "STATUS"; public static final String EXTRA_UUID = "UUID"; public static final String EXTRA_VALUE = "VALUE"; public static final String EXTRA_REQUEST = "REQUEST"; public static final String EXTRA_REASON = "REASON"; /** Source of device entries in the device list */ public static final int DEVICE_SOURCE_SCAN = 0; public static final int DEVICE_SOURCE_BONDED = 1; public static final int DEVICE_SOURCE_CONNECTED = 2; public static final UUID DESC_CCC = UUID .fromString("00002902-0000-1000-8000-00805f9b34fb"); public enum BLESDK { NOT_SUPPORTED, ANDROID, SAMSUNG, BROADCOM } private final IBinder mBinder = new LocalBinder(); private BLESDK mBleSDK; private IBle mBle; private Queue mRequestQueue = new LinkedList(); private BleRequest mCurrentRequest = null; private static final int REQUEST_TIMEOUT = 10 * 10; // total timeout = // REQUEST_TIMEOUT * // 100ms private boolean mCheckTimeout = false; private int mElapsed = 0; private Thread mRequestTimeout; private String mNotificationAddress; private Runnable mTimeoutRunnable = new Runnable() { @Override public void run() { Log.d(TAG, "monitoring thread start"); mElapsed = 0; try { while (mCheckTimeout) { // Log.d(TAG, "monitoring timeout seconds: " + mElapsed); Thread.sleep(100); mElapsed++; if (mElapsed > REQUEST_TIMEOUT && mCurrentRequest != null) { Log.d(TAG, "-processrequest type " + mCurrentRequest.type + " address " + mCurrentRequest.address + " [timeout]"); bleRequestFailed(mCurrentRequest.address, mCurrentRequest.type, FailReason.TIMEOUT); bleStatusAbnormal("-processrequest type " + mCurrentRequest.type + " address " + mCurrentRequest.address + " [timeout]"); if (mBle != null) { mBle.disconnect(mCurrentRequest.address); } new Thread(new Runnable() { @Override public void run() { mCurrentRequest = null; processNextRequest(); } }, "th-ble").start(); break; } } } catch (InterruptedException e) { e.printStackTrace(); Log.d(TAG, "monitoring thread exception"); } Log.d(TAG, "monitoring thread stop"); } }; public static IntentFilter getIntentFilter() { IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(BLE_NOT_SUPPORTED); intentFilter.addAction(BLE_NO_BT_ADAPTER); intentFilter.addAction(BLE_STATUS_ABNORMAL); intentFilter.addAction(BLE_REQUEST_FAILED); intentFilter.addAction(BLE_DEVICE_FOUND); intentFilter.addAction(BLE_GATT_CONNECTED); intentFilter.addAction(BLE_GATT_DISCONNECTED); intentFilter.addAction(BLE_SERVICE_DISCOVERED); intentFilter.addAction(BLE_CHARACTERISTIC_READ); intentFilter.addAction(BLE_CHARACTERISTIC_NOTIFICATION); intentFilter.addAction(BLE_CHARACTERISTIC_WRITE); intentFilter.addAction(BLE_CHARACTERISTIC_CHANGED); return intentFilter; } @Override public IBinder onBind(Intent intent) { return mBinder; } public class LocalBinder extends Binder { public BleService getService() { return BleService.this; } } @Override public void onCreate() { mBleSDK = getBleSDK(); if (mBleSDK == BLESDK.NOT_SUPPORTED) { return; } Log.d(TAG, " " + mBleSDK); if (mBleSDK == BLESDK.BROADCOM) { mBle = new BroadcomBle(this); } else if (mBleSDK == BLESDK.ANDROID) { mBle = new AndroidBle(this); } else if (mBleSDK == BLESDK.SAMSUNG) { mBle = new SamsungBle(this); } } protected void bleNotSupported() { Intent intent = new Intent(BleService.BLE_NOT_SUPPORTED); sendBroadcast(intent); } protected void bleNoBtAdapter() { Intent intent = new Intent(BleService.BLE_NO_BT_ADAPTER); sendBroadcast(intent); } private BLESDK getBleSDK() { if (getPackageManager().hasSystemFeature( PackageManager.FEATURE_BLUETOOTH_LE)) { // android 4.3 return BLESDK.ANDROID; } ArrayList libraries = new ArrayList(); for (String i : getPackageManager().getSystemSharedLibraryNames()) { libraries.add(i); } if (android.os.Build.VERSION.SDK_INT >= 17) { // android 4.2.2 if (libraries.contains("com.samsung.android.sdk.bt")) { return BLESDK.SAMSUNG; } else if (libraries.contains("com.broadcom.bt")) { return BLESDK.BROADCOM; } } bleNotSupported(); return BLESDK.NOT_SUPPORTED; } public IBle getBle() { return mBle; } /** * Send {@link BleService#BLE_DEVICE_FOUND} broadcast.
*
* Data in the broadcast intent:
* {@link BleService#EXTRA_DEVICE} device {@link BluetoothDevice}
* {@link BleService#EXTRA_RSSI} rssi int
* {@link BleService#EXTRA_SCAN_RECORD} scan record byte[]
* {@link BleService#EXTRA_SOURCE} source int, not used now
*/ protected void bleDeviceFound(BluetoothDevice device, int rssi, byte[] scanRecord, int source) { Log.d("blelib", "[" + new Date().toLocaleString() + "] device found " + device.getAddress()); Intent intent = new Intent(BleService.BLE_DEVICE_FOUND); intent.putExtra(BleService.EXTRA_DEVICE, device); intent.putExtra(BleService.EXTRA_RSSI, rssi); intent.putExtra(BleService.EXTRA_SCAN_RECORD, scanRecord); intent.putExtra(BleService.EXTRA_SOURCE, source); sendBroadcast(intent); } /** * Send {@link BleService#BLE_GATT_CONNECTED} broadcast.
*
* Data in the broadcast intent:
* {@link BleService#EXTRA_DEVICE} device {@link BluetoothDevice}
*/ protected void bleGattConnected(BluetoothDevice device) { Intent intent = new Intent(BLE_GATT_CONNECTED); intent.putExtra(EXTRA_DEVICE, device); intent.putExtra(EXTRA_ADDR, device.getAddress()); sendBroadcast(intent); requestProcessed(device.getAddress(), RequestType.CONNECT_GATT, true); } /** * Send {@link BleService#BLE_GATT_DISCONNECTED} broadcast.
*
* Data in the broadcast intent:
* {@link BleService#EXTRA_ADDR} device address {@link String}
* * @param address */ protected void bleGattDisConnected(String address) { Intent intent = new Intent(BLE_GATT_DISCONNECTED); intent.putExtra(EXTRA_ADDR, address); sendBroadcast(intent); requestProcessed(address, RequestType.CONNECT_GATT, false); } /** * Send {@link BleService#BLE_SERVICE_DISCOVERED} broadcast.
*
* Data in the broadcast intent:
* {@link BleService#EXTRA_ADDR} device address {@link String}
* * @param address */ protected void bleServiceDiscovered(String address) { Intent intent = new Intent(BLE_SERVICE_DISCOVERED); intent.putExtra(EXTRA_ADDR, address); sendBroadcast(intent); requestProcessed(address, RequestType.DISCOVER_SERVICE, true); } protected void requestProcessed(String address, RequestType requestType, boolean success) { if (mCurrentRequest != null && mCurrentRequest.type == requestType) { clearTimeoutThread(); Log.d(TAG, "-processrequest type " + requestType + " address " + address + " [success: " + success + "]"); if (!success) { bleRequestFailed(mCurrentRequest.address, mCurrentRequest.type, FailReason.RESULT_FAILED); } new Thread(new Runnable() { @Override public void run() { mCurrentRequest = null; processNextRequest(); } }, "th-ble").start(); } } private void clearTimeoutThread() { if (mRequestTimeout.isAlive()) { try { mCheckTimeout = false; mRequestTimeout.join(); mRequestTimeout = null; } catch (InterruptedException e) { e.printStackTrace(); } } } /** * Send {@link BleService#BLE_CHARACTERISTIC_READ} broadcast.
*
* Data in the broadcast intent:
* {@link BleService#EXTRA_ADDR} device address {@link String}
* {@link BleService#EXTRA_UUID} characteristic uuid {@link String}
* {@link BleService#EXTRA_STATUS} read status {@link Integer} Not used now
* {@link BleService#EXTRA_VALUE} data byte[]
* * @param address * @param uuid * @param status * @param value */ protected void bleCharacteristicRead(String address, String uuid, int status, byte[] value) { Intent intent = new Intent(BLE_CHARACTERISTIC_READ); intent.putExtra(EXTRA_ADDR, address); intent.putExtra(EXTRA_UUID, uuid); intent.putExtra(EXTRA_STATUS, status); intent.putExtra(EXTRA_VALUE, value); sendBroadcast(intent); requestProcessed(address, RequestType.READ_CHARACTERISTIC, true); } protected void addBleRequest(BleRequest request) { synchronized (mRequestQueue) { mRequestQueue.add(request); processNextRequest(); } } private synchronized void processNextRequest() { if (mCurrentRequest != null) { return; } if (mRequestQueue.isEmpty()) { return; } mCurrentRequest = mRequestQueue.remove(); Log.d(TAG, "+processrequest type " + mCurrentRequest.type + " address " + mCurrentRequest.address + " remark " + mCurrentRequest.remark); startTimeoutThread(); boolean ret = false; switch (mCurrentRequest.type) { case CONNECT_GATT: ret = ((IBleRequestHandler) mBle).connect(mCurrentRequest.address); break; case DISCOVER_SERVICE: ret = mBle.discoverServices(mCurrentRequest.address); break; case CHARACTERISTIC_NOTIFICATION: case CHARACTERISTIC_INDICATION: case CHARACTERISTIC_STOP_NOTIFICATION: ret = ((IBleRequestHandler) mBle).characteristicNotification( mCurrentRequest.address, mCurrentRequest.characteristic); break; case READ_CHARACTERISTIC: ret = ((IBleRequestHandler) mBle).readCharacteristic( mCurrentRequest.address, mCurrentRequest.characteristic); break; case WRITE_CHARACTERISTIC: ret = ((IBleRequestHandler) mBle).writeCharacteristic( mCurrentRequest.address, mCurrentRequest.characteristic); break; case READ_DESCRIPTOR: break; default: break; } if (!ret) { clearTimeoutThread(); Log.d(TAG, "-processrequest type " + mCurrentRequest.type + " address " + mCurrentRequest.address + " [fail start]"); bleRequestFailed(mCurrentRequest.address, mCurrentRequest.type, FailReason.START_FAILED); new Thread(new Runnable() { @Override public void run() { mCurrentRequest = null; processNextRequest(); } }, "th-ble").start(); } } private void startTimeoutThread() { mCheckTimeout = true; mRequestTimeout = new Thread(mTimeoutRunnable); mRequestTimeout.start(); } protected BleRequest getCurrentRequest() { return mCurrentRequest; } protected void setCurrentRequest(BleRequest mCurrentRequest) { this.mCurrentRequest = mCurrentRequest; } /** * Send {@link BleService#BLE_CHARACTERISTIC_NOTIFICATION} broadcast.
*
* Data in the broadcast intent:
* {@link BleService#EXTRA_ADDR} device address {@link String}
* {@link BleService#EXTRA_UUID} characteristic uuid {@link String}
* {@link BleService#EXTRA_STATUS} read status {@link Integer} Not used now
* * @param address * @param uuid * @param status */ protected void bleCharacteristicNotification(String address, String uuid, boolean isEnabled, int status) { Intent intent = new Intent(BLE_CHARACTERISTIC_NOTIFICATION); intent.putExtra(EXTRA_ADDR, address); intent.putExtra(EXTRA_UUID, uuid); intent.putExtra(EXTRA_VALUE, isEnabled); intent.putExtra(EXTRA_STATUS, status); sendBroadcast(intent); if (isEnabled) { requestProcessed(address, RequestType.CHARACTERISTIC_NOTIFICATION, true); } else { requestProcessed(address, RequestType.CHARACTERISTIC_STOP_NOTIFICATION, true); } setNotificationAddress(address); } /** * Send {@link BleService#BLE_CHARACTERISTIC_INDICATION} broadcast.
*
* Data in the broadcast intent:
* {@link BleService#EXTRA_ADDR} device address {@link String}
* {@link BleService#EXTRA_UUID} characteristic uuid {@link String}
* {@link BleService#EXTRA_STATUS} read status {@link Integer} Not used now
* * @param address * @param uuid * @param status */ protected void bleCharacteristicIndication(String address, String uuid, int status) { Intent intent = new Intent(BLE_CHARACTERISTIC_INDICATION); intent.putExtra(EXTRA_ADDR, address); intent.putExtra(EXTRA_UUID, uuid); intent.putExtra(EXTRA_STATUS, status); sendBroadcast(intent); requestProcessed(address, RequestType.CHARACTERISTIC_INDICATION, true); setNotificationAddress(address); } /** * Send {@link BleService#BLE_CHARACTERISTIC_WRITE} broadcast.
*
* Data in the broadcast intent:
* {@link BleService#EXTRA_ADDR} device address {@link String}
* {@link BleService#EXTRA_UUID} characteristic uuid {@link String}
* {@link BleService#EXTRA_STATUS} read status {@link Integer} Not used now
* * @param address * @param uuid * @param status */ protected void bleCharacteristicWrite(String address, String uuid, int status) { Intent intent = new Intent(BLE_CHARACTERISTIC_WRITE); intent.putExtra(EXTRA_ADDR, address); intent.putExtra(EXTRA_UUID, uuid); intent.putExtra(EXTRA_STATUS, status); sendBroadcast(intent); requestProcessed(address, RequestType.WRITE_CHARACTERISTIC, true); } /** * Send {@link BleService#BLE_CHARACTERISTIC_CHANGED} broadcast.
*
* Data in the broadcast intent:
* {@link BleService#EXTRA_ADDR} device address {@link String}
* {@link BleService#EXTRA_UUID} characteristic uuid {@link String}
* {@link BleService#EXTRA_VALUE} data byte[]
* * @param address * @param uuid * @param value */ protected void bleCharacteristicChanged(String address, String uuid, byte[] value) { Intent intent = new Intent(BLE_CHARACTERISTIC_CHANGED); intent.putExtra(EXTRA_ADDR, address); intent.putExtra(EXTRA_UUID, uuid); intent.putExtra(EXTRA_VALUE, value); sendBroadcast(intent); } /** * @param reason */ protected void bleStatusAbnormal(String reason) { Intent intent = new Intent(BLE_STATUS_ABNORMAL); intent.putExtra(EXTRA_VALUE, reason); sendBroadcast(intent); } /** * Sent when BLE request failed.
*
* Data in the broadcast intent:
* {@link BleService#EXTRA_ADDR} device address {@link String}
* {@link BleService#EXTRA_REQUEST} request type * {@link BleRequest.RequestType}
* {@link BleService#EXTRA_REASON} fail reason {@link BleRequest.FailReason}
*/ protected void bleRequestFailed(String address, RequestType type, FailReason reason) { Intent intent = new Intent(BLE_REQUEST_FAILED); intent.putExtra(EXTRA_ADDR, address); intent.putExtra(EXTRA_REQUEST, type); intent.putExtra(EXTRA_REASON, reason.ordinal()); sendBroadcast(intent); } protected String getNotificationAddress() { return mNotificationAddress; } protected void setNotificationAddress(String mNotificationAddress) { this.mNotificationAddress = mNotificationAddress; } } ================================================ FILE: BleLibrary/src/com/xtremeprog/sdk/ble/BroadcomBle.java ================================================ /** * This XPG software is supplied to you by Xtreme Programming Group, Inc. * ("XPG") in consideration of your agreement to the following terms, and your * use, installation, modification or redistribution of this XPG software * constitutes acceptance of these terms.� If you do not agree with these terms, * please do not use, install, modify or redistribute this XPG software. * * In consideration of your agreement to abide by the following terms, and * subject to these terms, XPG grants you a non-exclusive license, under XPG's * copyrights in this original XPG software (the "XPG Software"), to use and * redistribute the XPG Software, in source and/or binary forms; provided that * if you redistribute the XPG Software, with or without modifications, you must * retain this notice and the following text and disclaimers in all such * redistributions of the XPG Software. Neither the name, trademarks, service * marks or logos of XPG Inc. may be used to endorse or promote products derived * from the XPG Software without specific prior written permission from XPG.� * Except as expressly stated in this notice, no other rights or licenses, * express or implied, are granted by XPG herein, including but not limited to * any patent rights that may be infringed by your derivative works or by other * works in which the XPG Software may be incorporated. * * The XPG Software is provided by XPG on an "AS IS" basis.� XPG MAKES NO * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE, REGARDING THE XPG SOFTWARE OR ITS USE AND OPERATION ALONE OR IN * COMBINATION WITH YOUR PRODUCTS. * * IN NO EVENT SHALL XPG BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION * AND/OR DISTRIBUTION OF THE XPG SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER * THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR * OTHERWISE, EVEN IF XPG HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ABOUT XPG: Established since June 2005, Xtreme Programming Group, Inc. (XPG) * is a digital solutions company based in the United States and China. XPG * integrates cutting-edge hardware designs, mobile applications, and cloud * computing technologies to bring innovative products to the marketplace. XPG's * partners and customers include global leading corporations in semiconductor, * home appliances, health/wellness electronics, toys and games, and automotive * industries. Visit www.xtremeprog.com for more information. * * Copyright (C) 2013 Xtreme Programming Group, Inc. All Rights Reserved. */ package com.xtremeprog.sdk.ble; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.UUID; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothProfile; import com.broadcom.bt.gatt.BluetoothGatt; import com.broadcom.bt.gatt.BluetoothGattAdapter; import com.broadcom.bt.gatt.BluetoothGattCallback; import com.broadcom.bt.gatt.BluetoothGattCharacteristic; import com.broadcom.bt.gatt.BluetoothGattDescriptor; import com.broadcom.bt.gatt.BluetoothGattService; import com.xtremeprog.sdk.ble.BleRequest.RequestType; public class BroadcomBle implements IBle, IBleRequestHandler { private BluetoothAdapter mBtAdapter; private BleService mService; private BluetoothGatt mBluetoothGatt; private boolean mScanning; private String mAddress; private final BluetoothGattCallback mGattCallbacks = new BluetoothGattCallback() { @Override public void onAppRegistered(int status) { } @Override public void onScanResult(BluetoothDevice device, int rssi, byte[] scanRecord) { mService.bleDeviceFound(device, rssi, scanRecord, BleService.DEVICE_SOURCE_SCAN); } @Override public void onConnectionStateChange(BluetoothDevice device, int status, int newState) { if (mBluetoothGatt == null) { return; } if (newState == BluetoothProfile.STATE_CONNECTED) { mService.bleGattConnected(device); mBluetoothGatt.discoverServices(device); mAddress = device.getAddress(); } else if (newState == BluetoothProfile.STATE_DISCONNECTED) { mService.bleGattDisConnected(device.getAddress()); mAddress = null; } } @Override public void onServicesDiscovered(BluetoothDevice device, int status) { mService.bleServiceDiscovered(device.getAddress()); } @Override public void onCharacteristicRead( BluetoothGattCharacteristic characteristic, int status) { if (status == BluetoothGatt.GATT_SUCCESS) { mService.bleCharacteristicRead(mAddress, characteristic .getUuid().toString(), status, characteristic .getValue()); } } @Override public void onCharacteristicChanged( BluetoothGattCharacteristic characteristic) { String address = mService.getNotificationAddress(); mService.bleCharacteristicChanged(address, characteristic.getUuid() .toString(), characteristic.getValue()); } @Override public void onDescriptorRead(BluetoothGattDescriptor descriptor, int status) { BleRequest request = mService.getCurrentRequest(); String address = request.address; byte[] value = descriptor.getValue(); byte[] val_set = null; if (request.type == RequestType.CHARACTERISTIC_NOTIFICATION) { val_set = BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE; } else if (request.type == RequestType.CHARACTERISTIC_INDICATION) { val_set = BluetoothGattDescriptor.ENABLE_INDICATION_VALUE; } else { val_set = BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE; } if (Arrays.equals(value, val_set)) { if (request.type == RequestType.CHARACTERISTIC_NOTIFICATION) { mService.bleCharacteristicNotification(address, descriptor .getCharacteristic().getUuid().toString(), true, status); } else if (request.type == RequestType.CHARACTERISTIC_INDICATION) { mService.bleCharacteristicIndication(address, descriptor .getCharacteristic().getUuid().toString(), status); } else { mService.bleCharacteristicNotification(address, descriptor .getCharacteristic().getUuid().toString(), false, status); } return; } if (!descriptor.setValue(val_set)) { mService.requestProcessed(address, request.type, false); } mBluetoothGatt.writeDescriptor(descriptor); }; @Override public void onDescriptorWrite(BluetoothGattDescriptor descriptor, int status) { BleRequest request = mService.getCurrentRequest(); String address = request.address; if (request.type == RequestType.CHARACTERISTIC_NOTIFICATION || request.type == RequestType.CHARACTERISTIC_INDICATION || request.type == RequestType.CHARACTERISTIC_STOP_NOTIFICATION) { if (status != BluetoothGatt.GATT_SUCCESS) { mService.requestProcessed(address, request.type, false); return; } if (request.type == RequestType.CHARACTERISTIC_NOTIFICATION) { mService.bleCharacteristicNotification(address, descriptor .getCharacteristic().getUuid().toString(), true, status); } else if (request.type == RequestType.CHARACTERISTIC_INDICATION) { mService.bleCharacteristicIndication(address, descriptor .getCharacteristic().getUuid().toString(), status); } else { mService.bleCharacteristicNotification(address, descriptor .getCharacteristic().getUuid().toString(), false, status); } return; } }; }; private final BluetoothProfile.ServiceListener mProfileServiceListener = new BluetoothProfile.ServiceListener() { @Override public void onServiceConnected(int profile, BluetoothProfile proxy) { mBluetoothGatt = (BluetoothGatt) proxy; mBluetoothGatt.registerApp(mGattCallbacks); } @Override public void onServiceDisconnected(int profile) { for ( BluetoothDevice d : mBluetoothGatt.getConnectedDevices() ) { mBluetoothGatt.cancelConnection(d); } mBluetoothGatt = null; } }; public BroadcomBle(BleService service) { mService = service; mBtAdapter = BluetoothAdapter.getDefaultAdapter(); if (mBtAdapter == null) { mService.bleNoBtAdapter(); return; } BluetoothGattAdapter.getProfileProxy(mService, mProfileServiceListener, BluetoothGattAdapter.GATT); } @Override public void startScan() { if (mScanning) { return; } if (mBluetoothGatt == null) { mScanning = false; return; } mScanning = true; mBluetoothGatt.startScan(); } @Override public void stopScan() { if (!mScanning || mBluetoothGatt == null) { return; } mScanning = false; mBluetoothGatt.stopScan(); } @Override public boolean adapterEnabled() { if (mBtAdapter != null) { return mBtAdapter.isEnabled(); } return false; } @Override public boolean connect(String address) { BluetoothDevice device = mBtAdapter.getRemoteDevice(address); return mBluetoothGatt.connect(device, false); } @Override public void disconnect(String address) { BluetoothDevice device = mBtAdapter.getRemoteDevice(address); mBluetoothGatt.cancelConnection(device); } @Override public ArrayList getServices(String address) { ArrayList list = new ArrayList(); BluetoothDevice device = mBtAdapter.getRemoteDevice(address); List services = mBluetoothGatt .getServices(device); for (BluetoothGattService s : services) { list.add(new BleGattService(s)); } return list; } @Override public boolean requestReadCharacteristic(String address, BleGattCharacteristic characteristic) { mService.addBleRequest(new BleRequest(RequestType.READ_CHARACTERISTIC, address, characteristic)); return true; } @Override public boolean discoverServices(String address) { return true; } @Override public boolean readCharacteristic(String address, BleGattCharacteristic characteristic) { if (characteristic.getGattCharacteristicB() != null) { return mBluetoothGatt.readCharacteristic(characteristic .getGattCharacteristicB()); } return false; } @Override public BleGattService getService(String address, UUID uuid) { BluetoothGattService service = mBluetoothGatt.getService( mBtAdapter.getRemoteDevice(address), uuid); if (service == null) { return null; } else { return new BleGattService(service); } } @Override public boolean requestCharacteristicNotification(String address, BleGattCharacteristic characteristic) { mService.addBleRequest(new BleRequest( RequestType.CHARACTERISTIC_NOTIFICATION, address, characteristic)); return true; } @Override public boolean characteristicNotification(String address, BleGattCharacteristic characteristic) { BleRequest request = mService.getCurrentRequest(); BluetoothGattCharacteristic b = characteristic.getGattCharacteristicB(); boolean enable = true; if (request.type == RequestType.CHARACTERISTIC_STOP_NOTIFICATION) { enable = false; } if (!mBluetoothGatt.setCharacteristicNotification(b, enable)) { return false; } BluetoothGattDescriptor descriptor = b .getDescriptor(BleService.DESC_CCC); if (descriptor == null) { return false; } return mBluetoothGatt.readDescriptor(descriptor); } @Override public boolean requestWriteCharacteristic(String address, BleGattCharacteristic characteristic, String remark) { mService.addBleRequest(new BleRequest(RequestType.WRITE_CHARACTERISTIC, address, characteristic)); return true; } @Override public boolean writeCharacteristic(String address, BleGattCharacteristic characteristic) { return mBluetoothGatt.writeCharacteristic(characteristic .getGattCharacteristicB()); } @Override public boolean requestConnect(String address) { if (mAddress != null) { return false; } mService.addBleRequest(new BleRequest(RequestType.CONNECT_GATT, address)); return true; } @Override public String getBTAdapterMacAddr() { if (mBtAdapter != null) { return mBtAdapter.getAddress(); } return null; } @Override public boolean requestIndication(String address, BleGattCharacteristic characteristic) { mService.addBleRequest(new BleRequest( RequestType.CHARACTERISTIC_INDICATION, address, characteristic)); return true; } @Override public boolean requestStopNotification(String address, BleGattCharacteristic characteristic) { mService.addBleRequest(new BleRequest( RequestType.CHARACTERISTIC_STOP_NOTIFICATION, address, characteristic)); return true; } } ================================================ FILE: BleLibrary/src/com/xtremeprog/sdk/ble/IBle.java ================================================ /** * This XPG software is supplied to you by Xtreme Programming Group, Inc. * ("XPG") in consideration of your agreement to the following terms, and your * use, installation, modification or redistribution of this XPG software * constitutes acceptance of these terms.� If you do not agree with these terms, * please do not use, install, modify or redistribute this XPG software. * * In consideration of your agreement to abide by the following terms, and * subject to these terms, XPG grants you a non-exclusive license, under XPG's * copyrights in this original XPG software (the "XPG Software"), to use and * redistribute the XPG Software, in source and/or binary forms; provided that * if you redistribute the XPG Software, with or without modifications, you must * retain this notice and the following text and disclaimers in all such * redistributions of the XPG Software. Neither the name, trademarks, service * marks or logos of XPG Inc. may be used to endorse or promote products derived * from the XPG Software without specific prior written permission from XPG.� * Except as expressly stated in this notice, no other rights or licenses, * express or implied, are granted by XPG herein, including but not limited to * any patent rights that may be infringed by your derivative works or by other * works in which the XPG Software may be incorporated. * * The XPG Software is provided by XPG on an "AS IS" basis.� XPG MAKES NO * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE, REGARDING THE XPG SOFTWARE OR ITS USE AND OPERATION ALONE OR IN * COMBINATION WITH YOUR PRODUCTS. * * IN NO EVENT SHALL XPG BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION * AND/OR DISTRIBUTION OF THE XPG SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER * THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR * OTHERWISE, EVEN IF XPG HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ABOUT XPG: Established since June 2005, Xtreme Programming Group, Inc. (XPG) * is a digital solutions company based in the United States and China. XPG * integrates cutting-edge hardware designs, mobile applications, and cloud * computing technologies to bring innovative products to the marketplace. XPG's * partners and customers include global leading corporations in semiconductor, * home appliances, health/wellness electronics, toys and games, and automotive * industries. Visit www.xtremeprog.com for more information. * * Copyright (C) 2013 Xtreme Programming Group, Inc. All Rights Reserved. */ package com.xtremeprog.sdk.ble; import java.util.ArrayList; import java.util.UUID; public interface IBle { public String getBTAdapterMacAddr(); /** * Will receive broadcast {@link BleService#BLE_DEVICE_FOUND} if device * found. */ public void startScan(); /** * Stop BLE scan. */ public void stopScan(); /** * Check if bluetooth adapter is enabled. * * @return enabled */ public boolean adapterEnabled(); /** * Disconnect BLE device. Will receive * {@link BleService#BLE_GATT_DISCONNECTED} broadcast if device * disconnected. * * @param address * BLE device address. */ public void disconnect(String address); /** * Discover BLE services. Will receive * {@link BleService#BLE_SERVICE_DISCOVERED} broadcast if device service * discovered. * * @param address * @return */ public boolean discoverServices(String address); /** * Get discovered services for BLE device. Call this function after * {@link BleService#BLE_SERVICE_DISCOVERED} broadcast is received. * * @param address * @return List of {@link BleGattService} */ public ArrayList getServices(String address); /** * Get discovered service by uuid. Call this function after * {@link BleService#BLE_SERVICE_DISCOVERED} broadcast is received. * * @param address * @param uuid * @return {@link BleGattService} */ public BleGattService getService(String address, UUID uuid); /** * Request to connect a BLE device by address. Will receive * {@link BleService#BLE_GATT_CONNECTED} broadcast if device connected. * * @param address * @return if request be inserted into queue successfully. */ public boolean requestConnect(String address); /** * Request to read characteristic. Will receive * {@link BleService#BLE_CHARACTERISTIC_READ} broadcast if characteristic * read. * * @param address * @param characteristic * Get characteristic from {@link BleGattService} * @return if request be inserted into queue successfully. */ public boolean requestReadCharacteristic(String address, BleGattCharacteristic characteristic); /** * Request characteristic notification. Will receive * {@link BleService#BLE_CHARACTERISTIC_NOTIFICATION} broadcast if * notification set OK. When the characteristic's value changed, * {@link BleService#BLE_CHARACTERISTIC_CHANGED} broadcast will be received * also. * * @param address * @param characteristic * Get characteristic from {@link BleGattService} * @return if request be inserted into queue successfully. */ public boolean requestCharacteristicNotification(String address, BleGattCharacteristic characteristic); public boolean requestStopNotification(String address, BleGattCharacteristic characteristic); /** * Request characteristic indication. Will receive * {@link BleService#BLE_CHARACTERISTIC_INDICATION} broadcast if indication * set OK. When the characteristic's value changed, * {@link BleService#BLE_CHARACTERISTIC_CHANGED} broadcast will be received * also. * * @param address * @param characteristic * Get characteristic from {@link BleGattService} * @return if request be inserted into queue successfully. */ public boolean requestIndication(String address, BleGattCharacteristic characteristic); /** * Request write characteristic value. Will receive * {@link BleService#BLE_CHARACTERISTIC_WRITE} broadcast if characteristic * value be written. * * @param address * @param characteristic * Get characteristic from {@link BleGattService} * @param remark * For debug purpose. * @return if request be inserted into queue successfully. */ public boolean requestWriteCharacteristic(String address, BleGattCharacteristic characteristic, String remark); } ================================================ FILE: BleLibrary/src/com/xtremeprog/sdk/ble/IBleRequestHandler.java ================================================ /** * This XPG software is supplied to you by Xtreme Programming Group, Inc. * ("XPG") in consideration of your agreement to the following terms, and your * use, installation, modification or redistribution of this XPG software * constitutes acceptance of these terms.� If you do not agree with these terms, * please do not use, install, modify or redistribute this XPG software. * * In consideration of your agreement to abide by the following terms, and * subject to these terms, XPG grants you a non-exclusive license, under XPG's * copyrights in this original XPG software (the "XPG Software"), to use and * redistribute the XPG Software, in source and/or binary forms; provided that * if you redistribute the XPG Software, with or without modifications, you must * retain this notice and the following text and disclaimers in all such * redistributions of the XPG Software. Neither the name, trademarks, service * marks or logos of XPG Inc. may be used to endorse or promote products derived * from the XPG Software without specific prior written permission from XPG.� * Except as expressly stated in this notice, no other rights or licenses, * express or implied, are granted by XPG herein, including but not limited to * any patent rights that may be infringed by your derivative works or by other * works in which the XPG Software may be incorporated. * * The XPG Software is provided by XPG on an "AS IS" basis.� XPG MAKES NO * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE, REGARDING THE XPG SOFTWARE OR ITS USE AND OPERATION ALONE OR IN * COMBINATION WITH YOUR PRODUCTS. * * IN NO EVENT SHALL XPG BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION * AND/OR DISTRIBUTION OF THE XPG SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER * THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR * OTHERWISE, EVEN IF XPG HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ABOUT XPG: Established since June 2005, Xtreme Programming Group, Inc. (XPG) * is a digital solutions company based in the United States and China. XPG * integrates cutting-edge hardware designs, mobile applications, and cloud * computing technologies to bring innovative products to the marketplace. XPG's * partners and customers include global leading corporations in semiconductor, * home appliances, health/wellness electronics, toys and games, and automotive * industries. Visit www.xtremeprog.com for more information. * * Copyright (C) 2013 Xtreme Programming Group, Inc. All Rights Reserved. */ package com.xtremeprog.sdk.ble; public interface IBleRequestHandler { public boolean connect(String address); /** * @param address * @param characteristic * @return */ public boolean readCharacteristic(String address, BleGattCharacteristic characteristic); /** * @param address * @param characteristic * @return */ public boolean characteristicNotification(String address, BleGattCharacteristic characteristic); /** * @param address * @param characteristic * @return */ public boolean writeCharacteristic(String address, BleGattCharacteristic characteristic); } ================================================ FILE: BleLibrary/src/com/xtremeprog/sdk/ble/SamsungBle.java ================================================ /** * This XPG software is supplied to you by Xtreme Programming Group, Inc. * ("XPG") in consideration of your agreement to the following terms, and your * use, installation, modification or redistribution of this XPG software * constitutes acceptance of these terms.� If you do not agree with these terms, * please do not use, install, modify or redistribute this XPG software. * * In consideration of your agreement to abide by the following terms, and * subject to these terms, XPG grants you a non-exclusive license, under XPG's * copyrights in this original XPG software (the "XPG Software"), to use and * redistribute the XPG Software, in source and/or binary forms; provided that * if you redistribute the XPG Software, with or without modifications, you must * retain this notice and the following text and disclaimers in all such * redistributions of the XPG Software. Neither the name, trademarks, service * marks or logos of XPG Inc. may be used to endorse or promote products derived * from the XPG Software without specific prior written permission from XPG.� * Except as expressly stated in this notice, no other rights or licenses, * express or implied, are granted by XPG herein, including but not limited to * any patent rights that may be infringed by your derivative works or by other * works in which the XPG Software may be incorporated. * * The XPG Software is provided by XPG on an "AS IS" basis.� XPG MAKES NO * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE, REGARDING THE XPG SOFTWARE OR ITS USE AND OPERATION ALONE OR IN * COMBINATION WITH YOUR PRODUCTS. * * IN NO EVENT SHALL XPG BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION * AND/OR DISTRIBUTION OF THE XPG SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER * THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR * OTHERWISE, EVEN IF XPG HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ABOUT XPG: Established since June 2005, Xtreme Programming Group, Inc. (XPG) * is a digital solutions company based in the United States and China. XPG * integrates cutting-edge hardware designs, mobile applications, and cloud * computing technologies to bring innovative products to the marketplace. XPG's * partners and customers include global leading corporations in semiconductor, * home appliances, health/wellness electronics, toys and games, and automotive * industries. Visit www.xtremeprog.com for more information. * * Copyright (C) 2013 Xtreme Programming Group, Inc. All Rights Reserved. */ package com.xtremeprog.sdk.ble; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.UUID; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothProfile; import android.util.Log; import com.samsung.android.sdk.bt.gatt.BluetoothGatt; import com.samsung.android.sdk.bt.gatt.BluetoothGattAdapter; import com.samsung.android.sdk.bt.gatt.BluetoothGattCallback; import com.samsung.android.sdk.bt.gatt.BluetoothGattCharacteristic; import com.samsung.android.sdk.bt.gatt.BluetoothGattDescriptor; import com.samsung.android.sdk.bt.gatt.BluetoothGattService; import com.xtremeprog.sdk.ble.BleRequest.RequestType; public class SamsungBle implements IBle, IBleRequestHandler { protected static final String TAG = "blelib"; private BluetoothAdapter mBtAdapter; private BleService mService; private BluetoothGatt mBluetoothGatt; private boolean mScanning; private final BluetoothGattCallback mGattCallbacks = new BluetoothGattCallback() { @Override public void onAppRegistered(int status) { } @Override public void onScanResult(BluetoothDevice device, int rssi, byte[] scanRecord) { mService.bleDeviceFound(device, rssi, scanRecord, BleService.DEVICE_SOURCE_SCAN); } @Override public void onConnectionStateChange(BluetoothDevice device, int status, int newState) { if (mBluetoothGatt == null) { return; } if (status != BluetoothGatt.GATT_SUCCESS) { disconnect(device.getAddress()); mService.bleGattDisConnected(device.getAddress()); return; } if (newState == BluetoothProfile.STATE_CONNECTED) { mService.bleGattConnected(device); mService.addBleRequest(new BleRequest( RequestType.DISCOVER_SERVICE, device.getAddress())); } else if (newState == BluetoothProfile.STATE_DISCONNECTED) { mService.bleGattDisConnected(device.getAddress()); disconnect(device.getAddress()); } } @Override public void onServicesDiscovered(BluetoothDevice device, int status) { String address = device.getAddress(); if (status != BluetoothGatt.GATT_SUCCESS) { disconnect(address); mService.bleGattDisConnected(address); mService.requestProcessed(address, RequestType.DISCOVER_SERVICE, false); return; } mService.bleServiceDiscovered(device.getAddress()); } @Override public void onCharacteristicRead( BluetoothGattCharacteristic characteristic, int status) { BleRequest request = mService.getCurrentRequest(); String address = request.address; if (status != BluetoothGatt.GATT_SUCCESS) { mService.requestProcessed(address, RequestType.READ_CHARACTERISTIC, false); return; } mService.bleCharacteristicRead(address, characteristic.getUuid() .toString(), status, characteristic.getValue()); } @Override public void onCharacteristicChanged( BluetoothGattCharacteristic characteristic) { Log.d(TAG, "onCharacteristicChanged"); String address = mService.getNotificationAddress(); mService.bleCharacteristicChanged(address, characteristic.getUuid() .toString(), characteristic.getValue()); } @Override public void onCharacteristicWrite( BluetoothGattCharacteristic characteristic, int status) { BleRequest request = mService.getCurrentRequest(); String address = request.address; if (status != BluetoothGatt.GATT_SUCCESS) { mService.requestProcessed(address, RequestType.WRITE_CHARACTERISTIC, false); return; } mService.bleCharacteristicWrite(address, characteristic.getUuid() .toString(), status); }; @Override public void onDescriptorRead(BluetoothGattDescriptor descriptor, int status) { BleRequest request = mService.getCurrentRequest(); String address = request.address; byte[] value = descriptor.getValue(); byte[] val_set = null; if (request.type == RequestType.CHARACTERISTIC_NOTIFICATION) { val_set = BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE; } else if (request.type == RequestType.CHARACTERISTIC_INDICATION) { val_set = BluetoothGattDescriptor.ENABLE_INDICATION_VALUE; } else { val_set = BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE; } if (Arrays.equals(value, val_set)) { if (request.type == RequestType.CHARACTERISTIC_NOTIFICATION) { mService.bleCharacteristicNotification(address, descriptor .getCharacteristic().getUuid().toString(), true, status); } else if (request.type == RequestType.CHARACTERISTIC_INDICATION) { mService.bleCharacteristicIndication(address, descriptor .getCharacteristic().getUuid().toString(), status); } else { mService.bleCharacteristicNotification(address, descriptor .getCharacteristic().getUuid().toString(), false, status); } return; } if (!descriptor.setValue(val_set)) { mService.requestProcessed(address, request.type, false); } mBluetoothGatt.writeDescriptor(descriptor); }; @Override public void onDescriptorWrite(BluetoothGattDescriptor descriptor, int status) { BleRequest request = mService.getCurrentRequest(); String address = request.address; if (request.type == RequestType.CHARACTERISTIC_NOTIFICATION || request.type == RequestType.CHARACTERISTIC_INDICATION || request.type == RequestType.CHARACTERISTIC_STOP_NOTIFICATION) { if (status != BluetoothGatt.GATT_SUCCESS) { mService.requestProcessed(address, request.type, false); return; } if (request.type == RequestType.CHARACTERISTIC_NOTIFICATION) { mService.bleCharacteristicNotification(address, descriptor .getCharacteristic().getUuid().toString(), true, status); } else if (request.type == RequestType.CHARACTERISTIC_INDICATION) { mService.bleCharacteristicIndication(address, descriptor .getCharacteristic().getUuid().toString(), status); } else { mService.bleCharacteristicNotification(address, descriptor .getCharacteristic().getUuid().toString(), false, status); } return; } }; }; private final BluetoothProfile.ServiceListener mProfileServiceListener = new BluetoothProfile.ServiceListener() { @Override public void onServiceConnected(int profile, BluetoothProfile proxy) { mBluetoothGatt = (BluetoothGatt) proxy; mBluetoothGatt.registerApp(mGattCallbacks); } @Override public void onServiceDisconnected(int profile) { mBluetoothGatt = null; } }; public SamsungBle(BleService service) { mService = service; mBtAdapter = BluetoothAdapter.getDefaultAdapter(); if (mBtAdapter == null) { mService.bleNoBtAdapter(); return; } BluetoothGattAdapter.getProfileProxy(mService, mProfileServiceListener, BluetoothGattAdapter.GATT); } @Override public void startScan() { if (mScanning) { return; } if (mBluetoothGatt == null) { mScanning = false; return; } mScanning = true; mBluetoothGatt.startScan(); } @Override public void stopScan() { if (!mScanning || mBluetoothGatt == null) { return; } mScanning = false; mBluetoothGatt.stopScan(); } @Override public boolean adapterEnabled() { if (mBtAdapter != null) { return mBtAdapter.isEnabled(); } return false; } @Override public boolean connect(String address) { BluetoothDevice device = mBtAdapter.getRemoteDevice(address); return mBluetoothGatt.connect(device, false); } @Override public void disconnect(String address) { BluetoothDevice device = mBtAdapter.getRemoteDevice(address); mBluetoothGatt.cancelConnection(device); } @Override public ArrayList getServices(String address) { ArrayList list = new ArrayList(); BluetoothDevice device = mBtAdapter.getRemoteDevice(address); List services = mBluetoothGatt .getServices(device); for (BluetoothGattService s : services) { list.add(new BleGattService(s)); } return list; } @Override public boolean requestReadCharacteristic(String address, BleGattCharacteristic characteristic) { mService.addBleRequest(new BleRequest(RequestType.READ_CHARACTERISTIC, address, characteristic)); return true; } @Override public boolean discoverServices(String address) { return mBluetoothGatt.discoverServices(mBtAdapter .getRemoteDevice(address)); } @Override public boolean readCharacteristic(String address, BleGattCharacteristic characteristic) { return mBluetoothGatt.readCharacteristic(characteristic .getGattCharacteristicS()); } @Override public BleGattService getService(String address, UUID uuid) { BluetoothGattService service = mBluetoothGatt.getService( mBtAdapter.getRemoteDevice(address), uuid); if (service == null) { return null; } else { return new BleGattService(service); } } @Override public boolean requestCharacteristicNotification(String address, BleGattCharacteristic characteristic) { mService.addBleRequest(new BleRequest( RequestType.CHARACTERISTIC_NOTIFICATION, address, characteristic)); return true; } @Override public boolean characteristicNotification(String address, BleGattCharacteristic characteristic) { BluetoothGattCharacteristic c = characteristic.getGattCharacteristicS(); if (!mBluetoothGatt.setCharacteristicNotification(c, true)) { return false; } BluetoothGattDescriptor descriptor = c .getDescriptor(BleService.DESC_CCC); if (descriptor == null) { return false; } return mBluetoothGatt.readDescriptor(descriptor); } @Override public boolean requestWriteCharacteristic(String address, BleGattCharacteristic characteristic, String remark) { mService.addBleRequest(new BleRequest(RequestType.WRITE_CHARACTERISTIC, address, characteristic)); return true; } @Override public boolean writeCharacteristic(String address, BleGattCharacteristic characteristic) { return mBluetoothGatt.writeCharacteristic(characteristic .getGattCharacteristicS()); } @Override public boolean requestConnect(String address) { mService.addBleRequest(new BleRequest(RequestType.CONNECT_GATT, address)); return true; } @Override public String getBTAdapterMacAddr() { if (mBtAdapter != null) { return mBtAdapter.getAddress(); } return null; } @Override public boolean requestIndication(String address, BleGattCharacteristic characteristic) { mService.addBleRequest(new BleRequest( RequestType.CHARACTERISTIC_INDICATION, address, characteristic)); return true; } @Override public boolean requestStopNotification(String address, BleGattCharacteristic characteristic) { mService.addBleRequest(new BleRequest( RequestType.CHARACTERISTIC_STOP_NOTIFICATION, address, characteristic)); return true; } } ================================================ FILE: BluetoothLeGatt/.classpath ================================================ ================================================ FILE: BluetoothLeGatt/.project ================================================ DeviceScanActivity com.android.ide.eclipse.adt.ResourceManagerBuilder com.android.ide.eclipse.adt.PreCompilerBuilder org.eclipse.jdt.core.javabuilder com.android.ide.eclipse.adt.ApkBuilder com.android.ide.eclipse.adt.AndroidNature org.eclipse.jdt.core.javanature ================================================ FILE: BluetoothLeGatt/AndroidManifest.xml ================================================ ================================================ FILE: BluetoothLeGatt/project.properties ================================================ # This file is automatically generated by Android Tools. # Do not modify this file -- YOUR CHANGES WILL BE ERASED! # # This file must be checked in Version Control Systems. # # To customize properties used by the Ant build system edit # "ant.properties", and override values to adapt the script to your # project structure. # # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt # Project target. target=android-17 android.library.reference.1=../BleLibrary ================================================ FILE: BluetoothLeGatt/res/layout/actionbar_indeterminate_progress.xml ================================================ ================================================ FILE: BluetoothLeGatt/res/layout/activity_characteristic.xml ================================================