[IOT-1089] Change Android build system to accomodate both Android and Generic Java...
[contrib/iotivity.git] / java / iotivity-android / 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 caLeGattCharacteristicWriteCallback(
98             BluetoothGatt gatt, byte[] data, int status);
99
100     private native static void caLeGattCharacteristicChangedCallback(
101             BluetoothGatt gatt, byte[] data);
102
103     private native static void caLeGattDescriptorWriteCallback(BluetoothGatt gatt, int status);
104
105     private native static void caLeGattReliableWriteCompletedCallback(BluetoothGatt gatt,
106                                                                      int status);
107
108     private native static void caLeGattReadRemoteRssiCallback(BluetoothGatt gatt, int rssi,
109                                                              int status);
110
111     // Network Monitor
112     private native static void caLeStateChangedCallback(int state);
113
114     // bond state
115     private native static void caLeBondStateChangedCallback(String address);
116
117     // adapter state
118     private native static void caManagerAdapterStateChangedCallback(int state);
119
120     // bond state
121     private native static void caManagerBondStateChangedCallback(BluetoothDevice address);
122
123     private native static void caManagerLeServicesDiscoveredCallback(BluetoothGatt gatt,
124                                                                      int status);
125
126     private native static void caManagerLeRemoteRssiCallback(BluetoothGatt gatt, int rssi,
127                                                              int status);
128
129     // Callback
130     private static BluetoothAdapter.LeScanCallback mLeScanCallback =
131                    new BluetoothAdapter.LeScanCallback() {
132
133         @Override
134         public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
135
136             try {
137                 List<UUID> uuids = getUuids(scanRecord);
138                 for (UUID uuid : uuids) {
139                     Log.d(TAG, "UUID : " + uuid.toString());
140                     if(uuid.toString().contains(SERVICE_UUID.toLowerCase())) {
141                         Log.d(TAG, "we found that has the Device");
142                         Log.d(TAG, "scanned device address : " + device.getAddress());
143                         caLeScanCallback(device);
144                     }
145                 }
146             } catch(UnsatisfiedLinkError e) {
147
148             }
149         }
150     };
151
152     private static List<UUID> getUuids(final byte[] scanRecord) {
153         List<UUID> uuids = new ArrayList<UUID>();
154
155         int offset = 0;
156         while (offset < (scanRecord.length - 2)) {
157             int len = scanRecord[offset++];
158             if (len == 0)
159                 break;
160
161             int type = scanRecord[offset++];
162
163             switch (type) {
164             case 0x02:
165             case 0x03:
166                 while (len > 1) {
167                     int uuid16 = scanRecord[offset++];
168                     uuid16 += (scanRecord[offset++] << 8);
169                     len -= 2;
170                     uuids.add(UUID.fromString(String.format(
171                             "%08x-0000-1000-8000-00805f9b34fb", uuid16)));
172                 }
173                 break;
174             case 0x06:
175             case 0x07:
176                 while (len >= 16) {
177                     try {
178                         ByteBuffer buffer = ByteBuffer.wrap(scanRecord, offset++, 16).
179                                                             order(ByteOrder.LITTLE_ENDIAN);
180                         long mostSigBits = buffer.getLong();
181                         long leastSigBits = buffer.getLong();
182                         uuids.add(new UUID(leastSigBits, mostSigBits));
183                     } catch (IndexOutOfBoundsException e) {
184                         Log.e(TAG, e.toString());
185                         continue;
186                     } finally {
187                         offset += 15;
188                         len -= 16;
189                     }
190                 }
191                 break;
192             default:
193                 offset += (len - 1);
194                 break;
195             }
196         }
197         return uuids;
198     }
199
200     private static final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
201
202         @Override
203         public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
204             super.onConnectionStateChange(gatt, status, newState);
205
206             caLeGattConnectionStateChangeCallback(gatt, status, newState);
207             caManagerLeGattConnectionStateChangeCB(gatt, status, newState);
208             caLeGattNWConnectionStateChangeCallback(gatt, status, newState);
209         }
210
211         @Override
212         public void onServicesDiscovered(BluetoothGatt gatt, int status) {
213             super.onServicesDiscovered(gatt, status);
214
215             caLeGattServicesDiscoveredCallback(gatt, status);
216             caManagerLeServicesDiscoveredCallback(gatt, status);
217             caLeGattNWServicesDiscoveredCallback(gatt, status);
218         }
219
220         @Override
221         public void onCharacteristicRead(BluetoothGatt gatt,
222                 BluetoothGattCharacteristic characteristic, int status) {
223             super.onCharacteristicRead(gatt, characteristic, status);
224         }
225
226         @Override
227         public void onCharacteristicWrite(BluetoothGatt gatt,
228                 BluetoothGattCharacteristic characteristic, int status) {
229             super.onCharacteristicWrite(gatt, characteristic, status);
230
231             caLeGattCharacteristicWriteCallback(gatt, characteristic.getValue(), status);
232         }
233
234         @Override
235         public void onCharacteristicChanged(BluetoothGatt gatt,
236                 BluetoothGattCharacteristic characteristic) {
237             super.onCharacteristicChanged(gatt, characteristic);
238
239             caLeGattCharacteristicChangedCallback(gatt, characteristic.getValue());
240         }
241
242         @Override
243         public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor,
244                 int status) {
245             super.onDescriptorRead(gatt, descriptor, status);
246         }
247
248         @Override
249         public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor,
250                 int status) {
251             super.onDescriptorWrite(gatt, descriptor, status);
252
253             caLeGattDescriptorWriteCallback(gatt, status);
254         }
255
256         @Override
257         public void onReliableWriteCompleted(BluetoothGatt gatt, int status) {
258             super.onReliableWriteCompleted(gatt, status);
259         }
260
261         @Override
262         public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
263             super.onReadRemoteRssi(gatt, rssi, status);
264             caManagerLeRemoteRssiCallback(gatt, rssi, status);
265         }
266     };
267
268     private static final BroadcastReceiver mReceiver = new BroadcastReceiver() {
269
270         @Override
271         public void onReceive(Context context, Intent intent) {
272
273             String action = intent.getAction();
274
275             if (action != null && action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
276
277                 int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
278                                                BluetoothAdapter.ERROR);
279
280                 if (state == BluetoothAdapter.STATE_ON || state == BluetoothAdapter.STATE_OFF
281                         || state == BluetoothAdapter.STATE_TURNING_OFF)
282                 {
283                     caLeStateChangedCallback(state);
284                     caManagerAdapterStateChangedCallback(state);
285                 }
286             }
287
288             if (action != null && action.equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)) {
289
290                 int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE,
291                                                    BluetoothDevice.ERROR);
292
293                 if (bondState == BluetoothDevice.BOND_NONE) {
294                     if ((intent.getIntExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE,
295                             BluetoothDevice.ERROR) == BluetoothDevice.BOND_BONDED)) {
296                             BluetoothDevice device = intent
297                                 .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
298
299                         caManagerBondStateChangedCallback(device);
300                         caLeBondStateChangedCallback(device.getAddress());
301                     }
302                 }
303             }
304         }
305     };
306 }
307
308