• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.github.google.bumble.remotehci;
2 
3 import android.os.RemoteException;
4 import android.util.Log;
5 
6 import java.io.IOException;
7 
8 public class HciProxy {
9     private static final String TAG = "HciProxy";
10     private final HciServer mServer;
11     private final Listener mListener;
12     private int mCommandPacketsReceived;
13     private int mAclPacketsReceived;
14     private int mScoPacketsReceived;
15     private int mEventPacketsSent;
16     private int mAclPacketsSent;
17     private int mScoPacketsSent;
18 
HciProxy(int port, Listener listener)19     HciProxy(int port, Listener listener) throws HalException {
20         this.mListener = listener;
21 
22         // Instantiate a HAL to communicate with the hardware.
23         HciHal hciHal = HciHal.create(new HciHalCallback() {
24             @Override
25             public void onPacket(HciPacket.Type type, byte[] packet) {
26                 mServer.sendPacket(type, packet);
27 
28                 switch (type) {
29                     case EVENT:
30                         mEventPacketsSent += 1;
31                         break;
32 
33                     case ACL_DATA:
34                         mAclPacketsSent += 1;
35                         break;
36 
37                     case SCO_DATA:
38                         mScoPacketsSent += 1;
39                         break;
40                 }
41                 updateHciPacketCount();
42             }
43         });
44         if (hciHal == null) {
45             String message = "Could not instantiate a HAL instance";
46             Log.w(TAG, message);
47             throw new HalException(message);
48         }
49 
50         // Initialize the HAL.
51         HciHal.Status status = null;
52         try {
53             status = hciHal.initialize();
54         } catch (RemoteException | InterruptedException e) {
55             throw new HalException("Exception while initializing");
56         }
57         if (status != HciHal.Status.SUCCESS) {
58             String message = "HAL initialization failed: " + status.label;
59             Log.w(TAG, message);
60             throw new HalException(message);
61         }
62 
63         // Create a server to accept clients.
64         mServer = new HciServer(port, new HciServer.Listener() {
65             @Override
66             public void onHostConnectionState(boolean connected) {
67                 mListener.onHostConnectionState(connected);
68                 if (connected) {
69                     mCommandPacketsReceived = 0;
70                     mAclPacketsReceived = 0;
71                     mScoPacketsReceived = 0;
72                     mEventPacketsSent = 0;
73                     mAclPacketsSent = 0;
74                     mScoPacketsSent = 0;
75                     updateHciPacketCount();
76                 }
77             }
78 
79             @Override
80             public void onMessage(String message) {
81                 listener.onMessage(message);
82             }
83 
84             @Override
85             public void onPacket(HciPacket.Type type, byte[] packet) {
86                 Log.d(TAG, String.format("onPacket: type=%s, size=%d", type, packet.length));
87                 hciHal.sendPacket(type, packet);
88 
89                 switch (type) {
90                     case COMMAND:
91                         mCommandPacketsReceived += 1;
92                         break;
93 
94                     case ACL_DATA:
95                         mAclPacketsReceived += 1;
96                         break;
97 
98                     case SCO_DATA:
99                         mScoPacketsReceived += 1;
100                         break;
101                 }
102                 updateHciPacketCount();
103             }
104         });
105     }
106 
run()107     public void run() throws IOException {
108         mServer.run();
109     }
110 
updateHciPacketCount()111     private void updateHciPacketCount() {
112         mListener.onHciPacketCountChange(
113                 mCommandPacketsReceived,
114                 mAclPacketsReceived,
115                 mScoPacketsReceived,
116                 mEventPacketsSent,
117                 mAclPacketsSent,
118                 mScoPacketsSent
119         );
120     }
121 
122     public interface Listener {
onHostConnectionState(boolean connected)123         void onHostConnectionState(boolean connected);
124 
onHciPacketCountChange( int commandPacketsReceived, int aclPacketsReceived, int scoPacketsReceived, int eventPacketsSent, int aclPacketsSent, int scoPacketsSent )125         void onHciPacketCountChange(
126                 int commandPacketsReceived,
127                 int aclPacketsReceived,
128                 int scoPacketsReceived,
129                 int eventPacketsSent,
130                 int aclPacketsSent,
131                 int scoPacketsSent
132         );
133 
onMessage(String message)134         void onMessage(String message);
135     }
136 
137     public static class HalException extends RuntimeException {
138         public final String message;
HalException(String message)139         public HalException(String message) {
140             this.message = message;
141         }
142     }
143 }
144