Source code: org/bluej/core/Test.java
1 package org.bluej.core;
2
3 import java.util.*;
4 import java.io.*;
5 import java.math.*;
6
7 public class Test implements L2CAPLstn {
8 Hci client;
9 Hci server;
10
11 Test() throws BlueJException {
12 client = new Hci(0);
13 server = new Hci(1, this);
14 }
15
16 public static void output(String msg) {
17 System.out.println(">> " + msg);
18 }
19 static void outputDataElement(DataElement el, String prefix) {
20 BigInteger val;
21 String name;
22 int type = el.getDataType();
23 switch (type) {
24 case DataElement.NULL:
25 output(prefix + "NULL");
26 break;
27 case DataElement.U_INT_1: case DataElement.U_INT_2:
28 case DataElement.U_INT_4:
29 output(prefix + "UNS INTEGER " + el.getLong());
30 break;
31 case DataElement.U_INT_8: case DataElement.U_INT_16:
32 val = new BigInteger((byte[])el.getValue());
33 output(prefix + "UNS INTEGER " + val);
34 break;
35 case DataElement.INT_1: case DataElement.INT_2:
36 case DataElement.INT_4: case DataElement.INT_8:
37 output(prefix + "INTEGER " + el.getLong());
38 break;
39 case DataElement.INT_16:
40 val = new BigInteger((byte[])el.getValue());
41 output(prefix + "INTEGER " + val);
42 break;
43 case DataElement.URL: case DataElement.STRING:
44 name = (type == DataElement.URL ? "URL " : "STRING ");
45 output(prefix + name + (String)el.getValue());
46 break;
47 case DataElement.BOOL:
48 output(prefix + "BOOLEAN " + el.getBoolean());
49 break;
50 case DataElement.UUID:
51 output(prefix + "UUID " + (UUID)el.getValue());
52 break;
53 case DataElement.DATSEQ: case DataElement.DATALT:
54 name = (type == DataElement.DATSEQ ? "DATSEQ " : "DATALT ");
55 output(prefix + name);
56 Enumeration en = (Enumeration)el.getValue();
57 String subpre = prefix + " ";
58 while (en.hasMoreElements()) {
59 DataElement sub = (DataElement)en.nextElement();
60 outputDataElement(sub, subpre);
61 }
62 break;
63 }
64 }
65 static int readShort(byte[] data, int start) {
66 return (0xff & data[start]) << 8 | (0xff & data[start+1]);
67 }
68 static long readLong(byte[] data, int start) {
69 long val = 0;
70 for (int i = 0; i < 4; i++)
71 val = (val << 8) | (0xff & data[start+i]);
72 return val;
73 }
74 static DataElement[] getSubElements(DataElement seq) {
75 DataElement[] subs = new DataElement[seq.getSize()];
76 Enumeration scan = (Enumeration)seq.getValue();
77 int i = 0;
78 while (scan.hasMoreElements()) {
79 subs[i++] = (DataElement)scan.nextElement();
80 }
81 return subs;
82 }
83 static void dumpAttributes(DataElement list) {
84 output("dumping attributes");
85 DataElement[] elts = getSubElements(list);
86 int size = elts.length;
87 for (int k = 0; k < size; k += 2) {
88 DataElement e = elts[k];
89 DataElement v = elts[k+1];
90 long val = e.getLong();
91 output(" attribute id = " + Long.toHexString(val));
92 outputDataElement(v, " ");
93 int type = v.getDataType();
94 }
95 }
96 static int seq = 0;
97 static void dumpPacket(byte[] buf, int len) {
98 try {
99 File f = new File("/home/sca/dump-" + seq++);
100 OutputStream out = new FileOutputStream(f);
101 out.write(buf, 0, len);
102 out.close();
103 output("dumped packet to " + f.getName());
104 }
105 catch (Exception e) {
106 e.printStackTrace();
107 }
108 }
109 static void offline() {
110 boolean more = true;
111 while (more) {
112 try {
113 byte[] buf = new byte[1024];
114 File f = new File("/home/sca/dump-" + seq++);
115 InputStream in = new FileInputStream(f);
116 int nobytes = in.read(buf);
117 in.close();
118
119 output("packet length = " + nobytes);
120
121 output(Utils.bytesToString(buf, 0, nobytes, " "));
122
123 int size = readShort(buf, 5);
124 DataElement elt = DataElementUtils.readDataElement(
125 buf, 7, size);
126 int size2 = (new DataElementUtils(elt)).getSizeInBytes();
127 output("size1 = " + size);
128 output("size2 = " + size2);
129 dumpAttributes(elt);
130 }
131 catch (Exception e) {
132 if (!(e instanceof FileNotFoundException))
133 e.printStackTrace();
134 more = false;
135 }
136 }
137 System.exit(0);
138 }
139 public void newConnection(L2CAPConn conn) {
140 int mtuIn = conn.getMTUIn();
141 int mtuOut = conn.getMTUOut();
142 byte[] bufIn = new byte[mtuIn];
143 byte[] bufOut = new byte[mtuOut];
144 boolean more = true;
145 output("got a new connection");
146
147 while (more) {
148 try {
149 int inbytes = conn.read(bufIn);
150 if (inbytes == 1 && bufIn[0] == (byte)0xff) {
151 more = false;
152 }
153 else {
154 conn.write(bufIn, inbytes);
155 }
156 }
157 catch (Exception e) {
158 e.printStackTrace();
159 }
160 }
161 }
162
163 void run(String[] args) throws BlueJException {
164 long psm = Long.parseLong(args[0]);
165 int mtu = 16;
166 output("starting test");
167 output("iniitializing server");
168 server.listenStartL2CAP(psm, mtu, mtu);
169 //output("sleeping");
170 //try { Thread.sleep(10000); } catch (Exception e) {}
171 output("connecting to server");
172 L2CAPConn conn = client.connectL2CAP(psm, server.getAddress(),
173 mtu, mtu);
174 int mtuIn = conn.getMTUIn();
175 int mtuOut = conn.getMTUOut();
176 byte[] bufIn = new byte[mtuIn];
177 byte[] bufOut = new byte[mtuOut];
178 Random rand = new Random();
179 for (int i = 0; i < 10; i++ ) {
180 output("test packet " + i);
181 rand.nextBytes(bufOut);
182 conn.write(bufOut, mtuOut);
183 int nobytes = conn.read(bufIn);
184
185 if (nobytes != mtuOut)
186 throw new BlueJException("lengths do not match");
187 for (int j = 0; j < nobytes; j++)
188 if (bufIn[j] != bufOut[j])
189 throw new BlueJException("data corruption");
190 }
191 conn.close();
192 output("done");
193 client.close();
194 server.close();
195 }
196
197 void run2(String[] args) throws BlueJException {
198
199 // offline();
200 int hcidev = 1;
201 if (args.length > 0)
202 hcidev = Integer.parseInt(args[0]);
203 output("starting test");
204 Hci hci = new Hci(hcidev);
205 output("local address is " + hci.getAddress());
206 String[] devs = hci.discoverDevices(5, 10);
207 output("number of devs = " + devs.length);
208 for (int i = 0; i < devs.length; i++) {
209 output("remote address is " + devs[i]);
210 L2CAPConn conn = hci.connectL2CAP(0x0001, devs[i], 0, 0);
211 output("input MTU = " + conn.getMTUIn());
212 output("output MTU = " + conn.getMTUOut());
213
214 // make browse packet
215 SDPPacket pkt = new SDPPacket(0x1234, conn.getMTUOut());
216 DataElement elem = new DataElement(DataElement.DATSEQ);
217 DataElement pubBrowse = new DataElement(
218 DataElement.UUID, new UUID(0x1002));
219 elem.addElement(pubBrowse);
220 pkt.reset(0x02); // search service request
221 pkt.addDataElement(elem); // the browse UUID
222 pkt.addShort(0x0010); // 16 records max
223 pkt.addByte(0x00); // no continuation
224
225 pkt.write(conn);
226 output("send packet is " + pkt.dump());
227
228 output("reading packet");
229 int mtu = conn.getMTUIn();
230 byte[] data = new byte[mtu];
231 int nobytes = conn.read(data);
232 output("read back " + nobytes + " bytes");
233
234 if (data[0] == 0x03) {
235 int transid = readShort(data, 1);
236 int length = readShort(data, 3);
237 output("response packet - id: "
238 + Integer.toHexString(transid) + " length: "
239 + length);
240 // for a search service response
241 int tot = readShort(data, 5);
242 int cur = readShort(data, 7);
243 output("tot: " + tot + " cur: " +cur);
244 for (int j = 0; j < cur; j++) {
245 long serv = readLong(data, 9+4*j);
246
247 // service attribute
248 DataElement seq = new DataElement(
249 DataElement.DATSEQ);
250 DataElement range = new DataElement(
251 DataElement.U_INT_4, 0x0000ffffL);
252 seq.addElement(range);
253
254 pkt.reset(0x04); // service attribute
255 pkt.addLong(serv); // query the service
256 pkt.addShort(0x100); // 256 attributes
257 pkt.addDataElement(seq);
258 pkt.addByte(0x00); // non continuation
259 pkt.write(conn);
260 output("send packet is " + pkt.dump());
261
262 byte[] reply = new byte[mtu];
263 int noreply = conn.read(reply);
264 output("service = " + Long.toHexString(serv));
265 // dumpPacket(reply, noreply);
266 if (reply[0] == 0x05) {
267 output("service description");
268 int listLen = readShort(reply, 5);
269 output("len = " + listLen);
270 DataElement list =
271 DataElementUtils.readDataElement(
272 reply, 7, noreply);
273 if (list.getDataType() == DataElement.DATSEQ) {
274 dumpAttributes(list);
275 }
276 else {
277 output("error: should read a DATSEQ");
278 }
279 }
280 else {
281 output("read back " + noreply +
282 " bytes (code = " +
283 Integer.toHexString(reply[0]) + ")");
284 output("error code is " + readShort(reply, 5));
285 }
286 }
287 }
288 else {
289 output("unexpected response: " + data[0]);
290 }
291
292 conn.close();
293 }
294 hci.close();
295 output("done");
296 }
297 public static void main(String[] args) {
298 try {
299 Test test = new Test();
300 test.run(args);
301 }
302 catch (Exception e) {
303 e.printStackTrace();
304 System.exit(-1);
305 }
306 System.exit(0);
307 }
308 }