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