change the condition for BLE connected callback
[platform/upstream/iotivity.git] / android / android_api / base / src / main / java / org / iotivity / ca / CaLeClientInterface.java
1 /******************************************************************
2  *
3  * Copyright 2014 Samsung Electronics All Rights Reserved.
4  *
5  *
6  *
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
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
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.
18  *
19  ******************************************************************/
20
21 package org.iotivity.ca;
22
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;
28
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;
40
41 public class CaLeClientInterface {
42
43     private static String SERVICE_UUID = "ADE3D529-C784-4F63-A987-EB69F70EE816";
44     private static String TAG          = "Sample_Service : CaLeClientInterface";
45     private static Context mContext;
46
47     private CaLeClientInterface(Context context) {
48         caLeRegisterLeScanCallback(mLeScanCallback);
49         caLeRegisterGattCallback(mGattCallback);
50         mContext = context;
51         registerIntentFilter();
52     }
53
54     public static void getLeScanCallback() {
55         caLeRegisterLeScanCallback(mLeScanCallback);
56     }
57
58     public static void getLeGattCallback() {
59         caLeRegisterGattCallback(mGattCallback);
60     }
61
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);
67         return filter;
68     }
69
70     public static void destroyLeInterface() {
71         mContext.unregisterReceiver(mReceiver);
72     }
73
74     private native static void caLeRegisterLeScanCallback(BluetoothAdapter.LeScanCallback callback);
75
76     private native static void caLeRegisterGattCallback(BluetoothGattCallback callback);
77
78     // BluetoothAdapter.LeScanCallback
79     private native static void caLeScanCallback(BluetoothDevice device);
80
81     // BluetoothGattCallback
82     private native static void caLeGattConnectionStateChangeCallback(
83             BluetoothGatt gatt, int status, int newState);
84
85     // BluetoothGattCallback for Connection Manager
86     private native static void caManagerLeGattConnectionStateChangeCB(
87             BluetoothGatt gatt, int status, int newState);
88
89     private native static void caLeGattNWConnectionStateChangeCallback(
90             BluetoothGatt gatt, int status, int newState);
91
92     private native static void caLeGattServicesDiscoveredCallback(BluetoothGatt gatt, int status);
93
94     private native static void caLeGattNWServicesDiscoveredCallback(BluetoothGatt gatt,
95                                                                     int status);
96
97     private native static void caLeGattNWDescriptorWriteCallback(BluetoothGatt gatt, int status);
98
99     private native static void caLeGattCharacteristicWriteCallback(
100             BluetoothGatt gatt, byte[] data, int status);
101
102     private native static void caLeGattCharacteristicChangedCallback(
103             BluetoothGatt gatt, byte[] data);
104
105     private native static void caLeGattDescriptorWriteCallback(BluetoothGatt gatt, int status);
106
107     private native static void caLeGattReliableWriteCompletedCallback(BluetoothGatt gatt,
108                                                                      int status);
109
110     private native static void caLeGattReadRemoteRssiCallback(BluetoothGatt gatt, int rssi,
111                                                              int status);
112
113     // Network Monitor
114     private native static void caLeStateChangedCallback(int state);
115
116     // bond state
117     private native static void caLeBondStateChangedCallback(String address);
118
119     // adapter state
120     private native static void caManagerAdapterStateChangedCallback(int state);
121
122     // bond state
123     private native static void caManagerBondStateChangedCallback(BluetoothDevice address);
124
125     private native static void caManagerLeServicesDiscoveredCallback(BluetoothGatt gatt,
126                                                                      int status);
127
128     private native static void caManagerLeRemoteRssiCallback(BluetoothGatt gatt, int rssi,
129                                                              int status);
130
131     // Callback
132     private static BluetoothAdapter.LeScanCallback mLeScanCallback =
133                    new BluetoothAdapter.LeScanCallback() {
134
135         @Override
136         public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
137
138             try {
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);
146                     }
147                 }
148             } catch(UnsatisfiedLinkError e) {
149
150             }
151         }
152     };
153
154     private static List<UUID> getUuids(final byte[] scanRecord) {
155         List<UUID> uuids = new ArrayList<UUID>();
156
157         int offset = 0;
158         while (offset < (scanRecord.length - 2)) {
159             int len = scanRecord[offset++];
160             if (len == 0)
161                 break;
162
163             int type = scanRecord[offset++];
164
165             switch (type) {
166             case 0x02:
167             case 0x03:
168                 while (len > 1) {
169                     int uuid16 = scanRecord[offset++];
170                     uuid16 += (scanRecord[offset++] << 8);
171                     len -= 2;
172                     uuids.add(UUID.fromString(String.format(
173                             "%08x-0000-1000-8000-00805f9b34fb", uuid16)));
174                 }
175                 break;
176             case 0x06:
177             case 0x07:
178                 while (len >= 16) {
179                     try {
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());
187                         continue;
188                     } finally {
189                         offset += 15;
190                         len -= 16;
191                     }
192                 }
193                 break;
194             default:
195                 offset += (len - 1);
196                 break;
197             }
198         }
199         return uuids;
200     }
201
202     private static final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
203
204         @Override
205         public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
206             super.onConnectionStateChange(gatt, status, newState);
207
208             caLeGattConnectionStateChangeCallback(gatt, status, newState);
209             caManagerLeGattConnectionStateChangeCB(gatt, status, newState);
210             caLeGattNWConnectionStateChangeCallback(gatt, status, newState);
211         }
212
213         @Override
214         public void onServicesDiscovered(BluetoothGatt gatt, int status) {
215             super.onServicesDiscovered(gatt, status);
216
217             caLeGattServicesDiscoveredCallback(gatt, status);
218             caManagerLeServicesDiscoveredCallback(gatt, status);
219             caLeGattNWServicesDiscoveredCallback(gatt, status);
220         }
221
222         @Override
223         public void onCharacteristicRead(BluetoothGatt gatt,
224                 BluetoothGattCharacteristic characteristic, int status) {
225             super.onCharacteristicRead(gatt, characteristic, status);
226         }
227
228         @Override
229         public void onCharacteristicWrite(BluetoothGatt gatt,
230                 BluetoothGattCharacteristic characteristic, int status) {
231             super.onCharacteristicWrite(gatt, characteristic, status);
232
233             caLeGattCharacteristicWriteCallback(gatt, characteristic.getValue(), status);
234         }
235
236         @Override
237         public void onCharacteristicChanged(BluetoothGatt gatt,
238                 BluetoothGattCharacteristic characteristic) {
239             super.onCharacteristicChanged(gatt, characteristic);
240
241             caLeGattCharacteristicChangedCallback(gatt, characteristic.getValue());
242         }
243
244         @Override
245         public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor,
246                 int status) {
247             super.onDescriptorRead(gatt, descriptor, status);
248         }
249
250         @Override
251         public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor,
252                 int status) {
253             super.onDescriptorWrite(gatt, descriptor, status);
254
255             caLeGattDescriptorWriteCallback(gatt, status);
256             caLeGattNWDescriptorWriteCallback(gatt, status);
257         }
258
259         @Override
260         public void onReliableWriteCompleted(BluetoothGatt gatt, int status) {
261             super.onReliableWriteCompleted(gatt, status);
262         }
263
264         @Override
265         public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
266             super.onReadRemoteRssi(gatt, rssi, status);
267             caManagerLeRemoteRssiCallback(gatt, rssi, status);
268         }
269     };
270
271     private static final BroadcastReceiver mReceiver = new BroadcastReceiver() {
272
273         @Override
274         public void onReceive(Context context, Intent intent) {
275
276             String action = intent.getAction();
277
278             if (action != null && action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
279
280                 int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
281                                                BluetoothAdapter.ERROR);
282
283                 if (state == BluetoothAdapter.STATE_ON || state == BluetoothAdapter.STATE_OFF
284                         || state == BluetoothAdapter.STATE_TURNING_OFF)
285                 {
286                     caLeStateChangedCallback(state);
287                     caManagerAdapterStateChangedCallback(state);
288                 }
289             }
290
291             if (action != null && action.equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)) {
292
293                 int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE,
294                                                    BluetoothDevice.ERROR);
295
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);
301
302                         caManagerBondStateChangedCallback(device);
303                         caLeBondStateChangedCallback(device.getAddress());
304                     }
305                 }
306             }
307         }
308     };
309 }
310
311