1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
package com.github.google.bumble.remotehci;
import android.util.Log;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class HciServer {
private static final String TAG = "HciServer";
private static final int BUFFER_SIZE = 1024;
private final int mPort;
private final Listener mListener;
private OutputStream mOutputStream;
public interface Listener extends HciParser.Sink {
void onHostConnectionState(boolean connected);
void onMessage(String message);
}
HciServer(int port, Listener listener) {
this.mPort = port;
this.mListener = listener;
}
public void run() throws IOException {
for (;;) {
try {
loop();
} catch (IOException error) {
mListener.onMessage("Cannot listen on port " + mPort);
return;
}
}
}
private void loop() throws IOException {
mListener.onHostConnectionState(false);
try (ServerSocket serverSocket = new ServerSocket(mPort)) {
mListener.onMessage("Waiting for connection on port " + serverSocket.getLocalPort());
try (Socket clientSocket = serverSocket.accept()) {
mListener.onHostConnectionState(true);
mListener.onMessage("Connected");
HciParser parser = new HciParser(mListener);
InputStream inputStream = clientSocket.getInputStream();
synchronized (this) {
mOutputStream = clientSocket.getOutputStream();
}
byte[] buffer = new byte[BUFFER_SIZE];
try {
for (; ; ) {
int bytesRead = inputStream.read(buffer);
if (bytesRead < 0) {
Log.d(TAG, "end of stream");
break;
}
parser.feedData(buffer, bytesRead);
}
} catch (IOException error) {
Log.d(TAG, "exception in read loop: " + error);
}
}
} finally {
synchronized (this) {
mOutputStream = null;
}
}
}
public void sendPacket(HciPacket.Type type, byte[] packet) {
// Create a combined data buffer so we can write it out in a single call.
byte[] data = new byte[packet.length + 1];
data[0] = type.value;
System.arraycopy(packet, 0, data, 1, packet.length);
synchronized (this) {
if (mOutputStream != null) {
try {
mOutputStream.write(data);
} catch (IOException error) {
Log.w(TAG, "failed to write packet: " + error);
}
} else {
Log.d(TAG, "no client, dropping packet");
}
}
}
}
|