1 /******************************************************************
3 * Copyright 2014 Samsung Electronics All Rights Reserved.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 ******************************************************************/
21 package org.iotivity.ca;
23 import java.nio.ByteBuffer;
24 import java.nio.ByteOrder;
25 import java.util.ArrayList;
26 import java.util.List;
27 import java.util.UUID;
29 import android.bluetooth.BluetoothAdapter;
30 import android.bluetooth.BluetoothDevice;
31 import android.bluetooth.BluetoothGatt;
32 import android.bluetooth.BluetoothGattCallback;
33 import android.bluetooth.BluetoothGattCharacteristic;
34 import android.bluetooth.BluetoothGattDescriptor;
35 import android.content.BroadcastReceiver;
36 import android.content.Context;
37 import android.content.Intent;
38 import android.content.IntentFilter;
39 import android.util.Log;
41 public class CaLeClientInterface {
43 private static String SERVICE_UUID = "ADE3D529-C784-4F63-A987-EB69F70EE816";
44 private static String TAG = "Sample_Service : CaLeClientInterface";
45 private static Context mContext;
47 private CaLeClientInterface(Context context) {
48 caLeRegisterLeScanCallback(mLeScanCallback);
49 caLeRegisterGattCallback(mGattCallback);
51 registerIntentFilter();
54 public static void getLeScanCallback() {
55 caLeRegisterLeScanCallback(mLeScanCallback);
58 public static void getLeGattCallback() {
59 caLeRegisterGattCallback(mGattCallback);
62 private static IntentFilter registerIntentFilter() {
63 IntentFilter filter = new IntentFilter();
64 filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
65 filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
66 mContext.registerReceiver(mReceiver, filter);
70 public static void destroyLeInterface() {
71 mContext.unregisterReceiver(mReceiver);
74 private native static void caLeRegisterLeScanCallback(BluetoothAdapter.LeScanCallback callback);
76 private native static void caLeRegisterGattCallback(BluetoothGattCallback callback);
78 // BluetoothAdapter.LeScanCallback
79 private native static void caLeScanCallback(BluetoothDevice device);
81 // BluetoothGattCallback
82 private native static void caLeGattConnectionStateChangeCallback(
83 BluetoothGatt gatt, int status, int newState);
85 // BluetoothGattCallback for Connection Manager
86 private native static void caManagerLeGattConnectionStateChangeCB(
87 BluetoothGatt gatt, int status, int newState);
89 private native static void caLeGattNWConnectionStateChangeCallback(
90 BluetoothGatt gatt, int status, int newState);
92 private native static void caLeGattServicesDiscoveredCallback(BluetoothGatt gatt, int status);
94 private native static void caLeGattNWServicesDiscoveredCallback(BluetoothGatt gatt,
97 private native static void caLeGattNWDescriptorWriteCallback(BluetoothGatt gatt, int status);
99 private native static void caLeGattCharacteristicWriteCallback(
100 BluetoothGatt gatt, byte[] data, int status);
102 private native static void caLeGattCharacteristicChangedCallback(
103 BluetoothGatt gatt, byte[] data);
105 private native static void caLeGattDescriptorWriteCallback(BluetoothGatt gatt, int status);
107 private native static void caLeGattReliableWriteCompletedCallback(BluetoothGatt gatt,
110 private native static void caLeGattReadRemoteRssiCallback(BluetoothGatt gatt, int rssi,
114 private native static void caLeStateChangedCallback(int state);
117 private native static void caLeBondStateChangedCallback(String address);
120 private native static void caManagerAdapterStateChangedCallback(int state);
123 private native static void caManagerBondStateChangedCallback(BluetoothDevice address);
125 private native static void caManagerLeServicesDiscoveredCallback(BluetoothGatt gatt,
128 private native static void caManagerLeRemoteRssiCallback(BluetoothGatt gatt, int rssi,
132 private static BluetoothAdapter.LeScanCallback mLeScanCallback =
133 new BluetoothAdapter.LeScanCallback() {
136 public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
139 List<UUID> uuids = getUuids(scanRecord);
140 for (UUID uuid : uuids) {
141 Log.d(TAG, "UUID : " + uuid.toString());
142 if(uuid.toString().contains(SERVICE_UUID.toLowerCase())) {
143 Log.d(TAG, "we found that has the Device");
144 Log.d(TAG, "scanned device address : " + device.getAddress());
145 caLeScanCallback(device);
148 } catch(UnsatisfiedLinkError e) {
154 private static List<UUID> getUuids(final byte[] scanRecord) {
155 List<UUID> uuids = new ArrayList<UUID>();
158 while (offset < (scanRecord.length - 2)) {
159 int len = scanRecord[offset++];
163 int type = scanRecord[offset++];
169 int uuid16 = scanRecord[offset++];
170 uuid16 += (scanRecord[offset++] << 8);
172 uuids.add(UUID.fromString(String.format(
173 "%08x-0000-1000-8000-00805f9b34fb", uuid16)));
180 ByteBuffer buffer = ByteBuffer.wrap(scanRecord, offset++, 16).
181 order(ByteOrder.LITTLE_ENDIAN);
182 long mostSigBits = buffer.getLong();
183 long leastSigBits = buffer.getLong();
184 uuids.add(new UUID(leastSigBits, mostSigBits));
185 } catch (IndexOutOfBoundsException e) {
186 Log.e(TAG, e.toString());
202 private static final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
205 public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
206 super.onConnectionStateChange(gatt, status, newState);
208 caLeGattConnectionStateChangeCallback(gatt, status, newState);
209 caManagerLeGattConnectionStateChangeCB(gatt, status, newState);
210 caLeGattNWConnectionStateChangeCallback(gatt, status, newState);
214 public void onServicesDiscovered(BluetoothGatt gatt, int status) {
215 super.onServicesDiscovered(gatt, status);
217 caLeGattServicesDiscoveredCallback(gatt, status);
218 caManagerLeServicesDiscoveredCallback(gatt, status);
219 caLeGattNWServicesDiscoveredCallback(gatt, status);
223 public void onCharacteristicRead(BluetoothGatt gatt,
224 BluetoothGattCharacteristic characteristic, int status) {
225 super.onCharacteristicRead(gatt, characteristic, status);
229 public void onCharacteristicWrite(BluetoothGatt gatt,
230 BluetoothGattCharacteristic characteristic, int status) {
231 super.onCharacteristicWrite(gatt, characteristic, status);
233 caLeGattCharacteristicWriteCallback(gatt, characteristic.getValue(), status);
237 public void onCharacteristicChanged(BluetoothGatt gatt,
238 BluetoothGattCharacteristic characteristic) {
239 super.onCharacteristicChanged(gatt, characteristic);
241 caLeGattCharacteristicChangedCallback(gatt, characteristic.getValue());
245 public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor,
247 super.onDescriptorRead(gatt, descriptor, status);
251 public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor,
253 super.onDescriptorWrite(gatt, descriptor, status);
255 caLeGattDescriptorWriteCallback(gatt, status);
256 caLeGattNWDescriptorWriteCallback(gatt, status);
260 public void onReliableWriteCompleted(BluetoothGatt gatt, int status) {
261 super.onReliableWriteCompleted(gatt, status);
265 public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
266 super.onReadRemoteRssi(gatt, rssi, status);
267 caManagerLeRemoteRssiCallback(gatt, rssi, status);
271 private static final BroadcastReceiver mReceiver = new BroadcastReceiver() {
274 public void onReceive(Context context, Intent intent) {
276 String action = intent.getAction();
278 if (action != null && action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
280 int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
281 BluetoothAdapter.ERROR);
283 if (state == BluetoothAdapter.STATE_ON || state == BluetoothAdapter.STATE_OFF
284 || state == BluetoothAdapter.STATE_TURNING_OFF)
286 caLeStateChangedCallback(state);
287 caManagerAdapterStateChangedCallback(state);
291 if (action != null && action.equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)) {
293 int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE,
294 BluetoothDevice.ERROR);
296 if (bondState == BluetoothDevice.BOND_NONE) {
297 if ((intent.getIntExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE,
298 BluetoothDevice.ERROR) == BluetoothDevice.BOND_BONDED)) {
299 BluetoothDevice device = intent
300 .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
302 caManagerBondStateChangedCallback(device);
303 caLeBondStateChangedCallback(device.getAddress());