2 * Copyright (c) 2020 Project CHIP Authors
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
18 package chip.devicecontroller;
20 import android.bluetooth.BluetoothGatt;
21 import android.bluetooth.BluetoothGattCallback;
22 import android.util.Log;
24 /** Controller to interact with the CHIP device. */
25 public class ChipDeviceController {
26 private static final String TAG = ChipDeviceController.class.getSimpleName();
28 private long deviceControllerPtr;
29 private int connectionId;
30 private BluetoothGatt bleGatt;
31 private CompletionListener completionListener;
33 public ChipDeviceController() {
34 deviceControllerPtr = newDeviceController();
37 public void setCompletionListener(CompletionListener listener) {
38 completionListener = listener;
41 public BluetoothGatt getBluetoothGatt() {
45 public BluetoothGattCallback getCallback() {
46 return AndroidChipStack.getInstance().getCallback();
49 public void pairDevice(BluetoothGatt bleServer, long deviceId, long setupPincode) {
50 if (connectionId == 0) {
53 connectionId = AndroidChipStack.getInstance().addConnection(this);
54 if (connectionId == 0) {
55 Log.e(TAG, "Failed to add Bluetooth connection.");
56 completionListener.onError(new Exception("Failed to add Bluetooth connection."));
60 Log.d(TAG, "Bluetooth connection added with ID: " + connectionId);
61 Log.d(TAG, "Pairing device with ID: " + deviceId);
62 pairDevice(deviceControllerPtr, deviceId, connectionId, setupPincode);
64 Log.e(TAG, "Bluetooth connection already in use.");
65 completionListener.onError(new Exception("Bluetooth connection already in use."));
69 public void unpairDevice(long deviceId) {
70 unpairDevice(deviceControllerPtr, deviceId);
73 public void pairTestDeviceWithoutSecurity(String ipAddress) {
74 pairTestDeviceWithoutSecurity(deviceControllerPtr, ipAddress);
77 public void pairDevice(long deviceId, int connectionId, long pinCode) {
78 pairDevice(deviceControllerPtr, deviceId, connectionId, pinCode);
81 public void sendWiFiCredentials(String ssid, String password) {
82 sendWiFiCredentials(deviceControllerPtr, ssid, password);
85 public void sendThreadCredentials(int channel, int panId, byte[] xpanId, byte[] masterKey) {
86 sendThreadCredentials(deviceControllerPtr, channel, panId, xpanId, masterKey);
89 public boolean disconnectDevice(long deviceId) {
90 return disconnectDevice(deviceControllerPtr, deviceId);
93 public void onConnectDeviceComplete() {
94 completionListener.onConnectDeviceComplete();
97 public void onSendMessageComplete(String message) {
98 completionListener.onSendMessageComplete(message);
101 public void onNetworkCredentialsRequested() {
102 if (completionListener != null) {
103 completionListener.onNetworkCredentialsRequested();
107 public void onOperationalCredentialsRequested(byte[] csr) {
108 if (completionListener != null) {
109 completionListener.onOperationalCredentialsRequested(csr);
113 public void onStatusUpdate(int status) {
114 if (completionListener != null) {
115 completionListener.onStatusUpdate(status);
119 public void onPairingComplete(int errorCode) {
120 if (completionListener != null) {
121 completionListener.onPairingComplete(errorCode);
125 public void onPairingDeleted(int errorCode) {
126 if (completionListener != null) {
127 completionListener.onPairingDeleted(errorCode);
131 public void onNotifyChipConnectionClosed(int connId) {
132 // Clear connection state.
133 AndroidChipStack.getInstance().removeConnection(connId);
137 Log.d(TAG, "Calling onNotifyChipConnectionClosed()");
138 completionListener.onNotifyChipConnectionClosed();
141 public void onCloseBleComplete(int connId) {
142 if (releaseBluetoothGatt(connId)) {
143 Log.d(TAG, "Calling onCloseBleComplete()");
144 completionListener.onCloseBleComplete();
146 Log.d(TAG, "Skipped calling onCloseBleComplete(). Connection has already been closed.");
150 public void onError(Throwable error) {
151 completionListener.onError(error);
154 public void close() {
155 releaseBluetoothGatt(connectionId);
158 private boolean releaseBluetoothGatt(int connId) {
159 if (connectionId == 0) {
163 Log.d(TAG, "Closing GATT and removing connection for " + connId);
168 // Clear connection state.
169 AndroidChipStack.getInstance().removeConnection(connId);
175 public String getIpAddress(long deviceId) {
176 return getIpAddress(deviceControllerPtr, deviceId);
179 public void sendMessage(long deviceId, String message) {
180 sendMessage(deviceControllerPtr, deviceId, message);
183 public void sendCommand(long deviceId, ChipCommandType command, int value) {
184 sendCommand(deviceControllerPtr, deviceId, command, value);
187 public boolean openPairingWindow(long deviceId, int duration) {
188 return openPairingWindow(deviceControllerPtr, deviceId, duration);
191 public boolean isActive(long deviceId) {
192 return isActive(deviceControllerPtr, deviceId);
195 private native long newDeviceController();
197 private native void pairDevice(
198 long deviceControllerPtr, long deviceId, int connectionId, long pinCode);
200 private native void unpairDevice(long deviceControllerPtr, long deviceId);
202 private native void pairTestDeviceWithoutSecurity(long deviceControllerPtr, String ipAddress);
204 private native void sendWiFiCredentials(long deviceControllerPtr, String ssid, String password);
206 private native void sendThreadCredentials(
207 long deviceControllerPtr, int channel, int panId, byte[] xpanId, byte[] masterKey);
209 private native boolean disconnectDevice(long deviceControllerPtr, long deviceId);
211 private native void deleteDeviceController(long deviceControllerPtr);
213 private native String getIpAddress(long deviceControllerPtr, long deviceId);
215 private native void sendMessage(long deviceControllerPtr, long deviceId, String message);
217 private native void sendCommand(
218 long deviceControllerPtr, long deviceId, ChipCommandType command, int value);
220 private native boolean openPairingWindow(long deviceControllerPtr, long deviceId, int duration);
222 private native boolean isActive(long deviceControllerPtr, long deviceId);
225 System.loadLibrary("CHIPController");
228 @SuppressWarnings("deprecation")
229 protected void finalize() throws Throwable {
232 if (deviceControllerPtr != 0) {
233 deleteDeviceController(deviceControllerPtr);
234 deviceControllerPtr = 0;
238 /** Interface to listen for callbacks from CHIPDeviceController. */
239 public interface CompletionListener {
241 /** Notifies the completion of "ConnectDevice" command. */
242 void onConnectDeviceComplete();
244 /** Notifies the completion of "SendMessage" echo command. */
245 void onSendMessageComplete(String message);
247 /** Notifies that the device is ready to receive Wi-Fi network credentials. */
248 void onNetworkCredentialsRequested();
250 /** Notifies that the device is ready to receive operational credentials. */
251 void onOperationalCredentialsRequested(byte[] csr);
253 /** Notifies the pairing status. */
254 void onStatusUpdate(int status);
256 /** Notifies the completion of pairing. */
257 void onPairingComplete(int errorCode);
259 /** Notifies the deletion of pairing session. */
260 void onPairingDeleted(int errorCode);
262 /** Notifies that the Chip connection has been closed. */
263 void onNotifyChipConnectionClosed();
265 /** Notifies the completion of the "close BLE connection" command. */
266 void onCloseBleComplete();
268 /** Notifies the listener of the error. */
269 void onError(Throwable error);