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