diff options
Diffstat (limited to 'obd2-lib/src/com/android/car/obd2/connections/BluetoothConnection.java')
-rw-r--r-- | obd2-lib/src/com/android/car/obd2/connections/BluetoothConnection.java | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/obd2-lib/src/com/android/car/obd2/connections/BluetoothConnection.java b/obd2-lib/src/com/android/car/obd2/connections/BluetoothConnection.java new file mode 100644 index 00000000..2d1a13e1 --- /dev/null +++ b/obd2-lib/src/com/android/car/obd2/connections/BluetoothConnection.java | |||
@@ -0,0 +1,125 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 The Android Open Source Project | ||
3 | * | ||
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | * you may not use this file except in compliance with the License. | ||
6 | * You may obtain a copy of the License at | ||
7 | * | ||
8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | * | ||
10 | * Unless required by applicable law or agreed to in writing, software | ||
11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | * See the License for the specific language governing permissions and | ||
14 | * limitations under the License. | ||
15 | */ | ||
16 | |||
17 | package com.android.car.obd2.connections; | ||
18 | |||
19 | import android.bluetooth.BluetoothAdapter; | ||
20 | import android.bluetooth.BluetoothDevice; | ||
21 | import android.bluetooth.BluetoothSocket; | ||
22 | import android.util.Log; | ||
23 | import com.android.car.obd2.Obd2Connection; | ||
24 | import java.io.IOException; | ||
25 | import java.io.InputStream; | ||
26 | import java.io.OutputStream; | ||
27 | import java.util.Objects; | ||
28 | import java.util.UUID; | ||
29 | |||
30 | public class BluetoothConnection implements Obd2Connection.UnderlyingTransport { | ||
31 | |||
32 | /** | ||
33 | * This is the well-known UUID for the Bluetooth SPP (Serial Port Profile) | ||
34 | */ | ||
35 | private static final UUID SERIAL_PORT_PROFILE = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); | ||
36 | |||
37 | private final BluetoothDevice mDevice; | ||
38 | private BluetoothSocket mSocket = null; | ||
39 | |||
40 | public static final String TAG = BluetoothConnection.class.getSimpleName(); | ||
41 | |||
42 | public BluetoothConnection(String bluetoothAddress) { | ||
43 | this(BluetoothAdapter.getDefaultAdapter().getRemoteDevice(bluetoothAddress)); | ||
44 | } | ||
45 | |||
46 | public BluetoothConnection(BluetoothDevice device) { | ||
47 | mDevice = Objects.requireNonNull(device); | ||
48 | connect(); | ||
49 | } | ||
50 | |||
51 | @Override | ||
52 | public String getAddress() { | ||
53 | return mDevice.getAddress(); | ||
54 | } | ||
55 | |||
56 | /** | ||
57 | * Establish an RFCOMM connection to the remote device. | ||
58 | * | ||
59 | * Assumes there is no existing connection. | ||
60 | * | ||
61 | * This method may take time to return (or even not return in pathological cases). | ||
62 | * It is a good idea to wrap it in some kind of Promise-like object. | ||
63 | * | ||
64 | * @return true if it could connect, false otherwise | ||
65 | */ | ||
66 | private boolean connect() { | ||
67 | try { | ||
68 | mSocket = mDevice.createRfcommSocketToServiceRecord(SERIAL_PORT_PROFILE); | ||
69 | mSocket.connect(); | ||
70 | } catch (IOException e) { | ||
71 | Log.w(TAG, "BluetoothConnection couldn't be established due to an exception: " + e); | ||
72 | mSocket = null; | ||
73 | return false; | ||
74 | } | ||
75 | return mSocket.isConnected(); | ||
76 | } | ||
77 | |||
78 | @Override | ||
79 | public boolean isConnected() { | ||
80 | return mSocket != null && mSocket.isConnected(); | ||
81 | } | ||
82 | |||
83 | private void close() { | ||
84 | if (isConnected()) { | ||
85 | try { | ||
86 | mSocket.close(); | ||
87 | } catch (IOException e) { | ||
88 | // we are letting go of the connection anyway, so log and continue | ||
89 | Log.w(TAG, "IOException during BluetoothSocket close(): " + e); | ||
90 | } finally { | ||
91 | mSocket = null; | ||
92 | } | ||
93 | } | ||
94 | } | ||
95 | |||
96 | @Override | ||
97 | public boolean reconnect() { | ||
98 | close(); | ||
99 | return connect(); | ||
100 | } | ||
101 | |||
102 | @Override | ||
103 | public InputStream getInputStream() { | ||
104 | if (isConnected()) { | ||
105 | try { | ||
106 | return mSocket.getInputStream(); | ||
107 | } catch (IOException e) { | ||
108 | Log.w(TAG, "failed to get Bluetooth input stream: " + e); | ||
109 | } | ||
110 | } | ||
111 | return null; | ||
112 | } | ||
113 | |||
114 | @Override | ||
115 | public OutputStream getOutputStream() { | ||
116 | if (isConnected()) { | ||
117 | try { | ||
118 | return mSocket.getOutputStream(); | ||
119 | } catch (IOException e) { | ||
120 | Log.w(TAG, "failed to get Bluetooth output stream: " + e); | ||
121 | } | ||
122 | } | ||
123 | return null; | ||
124 | } | ||
125 | } | ||