1bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde/*
2bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde* Copyright (C) 2014 Samsung System LSI
3bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde*
4bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde* Licensed under the Apache License, Version 2.0 (the "License");
5bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde* you may not use this file except in compliance with the License.
6bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde* You may obtain a copy of the License at
7bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde*
8bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde*      http://www.apache.org/licenses/LICENSE-2.0
9bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde*
10bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde* Unless required by applicable law or agreed to in writing, software
11bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde* distributed under the License is distributed on an "AS IS" BASIS,
12bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde* See the License for the specific language governing permissions and
14bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde* limitations under the License.
15bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde*/
16bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
17bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondepackage com.android.bluetooth.tests;
18bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
19bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport java.io.IOException;
20bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport java.io.PipedInputStream;
21bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport java.io.PipedOutputStream;
22bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport java.util.ArrayList;
23bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport java.util.concurrent.CountDownLatch;
24bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
25bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport javax.obex.HeaderSet;
26bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport javax.obex.ObexTransport;
27bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport javax.obex.Operation;
28bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport javax.obex.ResponseCodes;
295a60e47497f21f64e6d79420dc4c56c1907df22akschulzimport javax.obex.ServerRequestHandler;
30bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
315a60e47497f21f64e6d79420dc4c56c1907df22akschulzimport junit.framework.Assert;
32bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport android.annotation.TargetApi;
33bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport android.bluetooth.BluetoothAdapter;
34bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport android.bluetooth.BluetoothDevice;
35bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport android.bluetooth.BluetoothServerSocket;
36bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport android.bluetooth.BluetoothSocket;
37bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport android.bluetooth.BluetoothUuid;
385a60e47497f21f64e6d79420dc4c56c1907df22akschulzimport android.bluetooth.SdpMasRecord;
39bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport android.content.BroadcastReceiver;
40bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport android.content.Context;
41bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport android.content.Intent;
42bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport android.content.IntentFilter;
435a60e47497f21f64e6d79420dc4c56c1907df22akschulzimport android.net.LocalServerSocket;
445a60e47497f21f64e6d79420dc4c56c1907df22akschulzimport android.net.LocalSocket;
45bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport android.os.Build;
46bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport android.os.Debug;
47bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport android.os.ParcelUuid;
48bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport android.test.AndroidTestCase;
49bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport android.util.Log;
50bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
51bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport com.android.bluetooth.BluetoothObexTransport;
52bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport com.android.bluetooth.sdp.SdpManager;
535a60e47497f21f64e6d79420dc4c56c1907df22akschulzimport com.android.bluetooth.tests.TestSequencer.OPTYPE;
54bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
55bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde/**
56bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde * Test either using the reference ril without a modem, or using a RIL implementing the
57bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde * BT SAP API, by providing the rild-bt socket as well as the extended API functions for SAP.
58bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde *
59bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde */
60bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde@TargetApi(Build.VERSION_CODES.KITKAT)
615a60e47497f21f64e6d79420dc4c56c1907df22akschulzpublic class ObexTest extends AndroidTestCase implements ITestSequenceConfigurator {
62bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    protected static String TAG = "ObexTest";
63bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    protected static final boolean D = true;
64bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    protected static final boolean TRACE = false;
65bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    protected static final boolean DELAY_PASS_30_SEC = false;
66bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    public static final long PROGRESS_INTERVAL_MS = 1000;
67bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    private static final ObexTestParams defaultParams =
685a60e47497f21f64e6d79420dc4c56c1907df22akschulz            new ObexTestParams(2*8092, 0, 2*1024*1024);
69bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
70bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    private static final ObexTestParams throttle100Params =
715a60e47497f21f64e6d79420dc4c56c1907df22akschulz            new ObexTestParams(2*8092, 100000, 1024*1024);
72bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
73bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    private static final ObexTestParams smallParams =
74bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            new ObexTestParams(2*8092, 0, 2*1024);
75bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
76bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    private static final ObexTestParams hugeParams =
775a60e47497f21f64e6d79420dc4c56c1907df22akschulz            new ObexTestParams(2*8092, 0, 100*1024*1024);
78bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
795a60e47497f21f64e6d79420dc4c56c1907df22akschulz    private static final int SMALL_OPERATION_COUNT = 1000;
80bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    private static final int CONNECT_OPERATION_COUNT = 4500;
81bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
82bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    private static final int L2CAP_PSM = 29; /* If SDP is not used */
83bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    private static final int RFCOMM_CHANNEL = 29; /* If SDP is not used */
84bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
855a60e47497f21f64e6d79420dc4c56c1907df22akschulz    //public static final String SERVER_ADDRESS = "10:68:3F:5E:F9:2E";
865a60e47497f21f64e6d79420dc4c56c1907df22akschulz    public static final String SERVER_ADDRESS = "F8:CF:C5:A8:70:7E";
87bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
88bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    private static final String SDP_SERVER_NAME = "Samsung Server";
89bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    private static final String SDP_CLIENT_NAME = "Samsung Client";
90bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
915a60e47497f21f64e6d79420dc4c56c1907df22akschulz    private static final long SDP_FEATURES  = 0x87654321L; /* 32 bit */
92bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    private static final int SDP_MSG_TYPES  = 0xf1;       /*  8 bit */
93bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    private static final int SDP_MAS_ID     = 0xCA;       /*  8 bit */
94bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    private static final int SDP_VERSION    = 0xF0C0;     /* 16 bit */
95bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    public static final ParcelUuid SDP_UUID_OBEX_MAS = BluetoothUuid.MAS;
96bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
97bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    private static int sSdpHandle = -1;
985a60e47497f21f64e6d79420dc4c56c1907df22akschulz    private static final ObexTestDataHandler sDataHandler = new ObexTestDataHandler("(Client)");
995a60e47497f21f64e6d79420dc4c56c1907df22akschulz    private static final ISeqStepValidator sResponseCodeValidator = new ResponseCodeValidator();
1005a60e47497f21f64e6d79420dc4c56c1907df22akschulz    private static final ISeqStepValidator sDataValidator = new DataValidator();
1015a60e47497f21f64e6d79420dc4c56c1907df22akschulz
102bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
103bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    private enum SequencerType {
104bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        SEQ_TYPE_PAYLOAD,
105bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        SEQ_TYPE_CONNECT_DISCONNECT
106bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    }
107bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
108bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    private Context mContext = null;
109bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    private int mChannelType = 0;
110bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
111bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    public ObexTest() {
112bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        super();
113bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    }
114bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
115bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    /**
116bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * Test that a connection can be established.
117bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * WARNING: The performance of the pipe implementation is not good. I'm only able to get a
118bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * throughput of around 220 kbyte/sec - less that when using Bluetooth :-)
1195a60e47497f21f64e6d79420dc4c56c1907df22akschulz     * UPDATE: Did a local socket implementation below to replace this...
1205a60e47497f21f64e6d79420dc4c56c1907df22akschulz     *         This has a throughput of more than 4000 kbyte/s
121bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     */
122bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    public void testLocalPipes() {
123bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        mContext = this.getContext();
124bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        System.out.println("Setting up pipes...");
125bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
126bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        PipedInputStream clientInStream = null;
127bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        PipedOutputStream clientOutStream = null;
128bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        PipedInputStream serverInStream = null;
129bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        PipedOutputStream serverOutStream = null;
130bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        ObexPipeTransport clientTransport = null;
131bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        ObexPipeTransport serverTransport = null;
132bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
133bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        try {
134bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            /* Create and interconnect local pipes for transport */
135bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            clientInStream = new PipedInputStream(5*8092);
136bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            clientOutStream = new PipedOutputStream();
137bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            serverInStream = new PipedInputStream(clientOutStream, 5*8092);
138bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            serverOutStream = new PipedOutputStream(clientInStream);
139bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
140bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            /* Create the OBEX transport objects to wrap the pipes - enable SRM */
141bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            clientTransport = new ObexPipeTransport(clientInStream, clientOutStream, true);
142bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            serverTransport = new ObexPipeTransport(serverInStream, serverOutStream, true);
143bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
144bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            TestSequencer sequencer = createBtPayloadTestSequence(clientTransport, serverTransport);
145bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
146bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            //Debug.startMethodTracing("ObexTrace");
1475a60e47497f21f64e6d79420dc4c56c1907df22akschulz            assertTrue(sequencer.run(mContext));
148bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            //Debug.stopMethodTracing();
149bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        } catch (IOException e) {
150bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            Log.e(TAG, "IOException", e);
151bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        }
152bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    }
153bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
1545a60e47497f21f64e6d79420dc4c56c1907df22akschulz    /**
1555a60e47497f21f64e6d79420dc4c56c1907df22akschulz     * Run the test sequence using a local socket.
1565a60e47497f21f64e6d79420dc4c56c1907df22akschulz     * Throughput around 4000 kbyte/s - with a larger OBEX package size.
1575a60e47497f21f64e6d79420dc4c56c1907df22akschulz     */
1585a60e47497f21f64e6d79420dc4c56c1907df22akschulz    public void testLocalSockets() {
1595a60e47497f21f64e6d79420dc4c56c1907df22akschulz        mContext = this.getContext();
1605a60e47497f21f64e6d79420dc4c56c1907df22akschulz        System.out.println("Setting up sockets...");
1615a60e47497f21f64e6d79420dc4c56c1907df22akschulz
1625a60e47497f21f64e6d79420dc4c56c1907df22akschulz        try {
1635a60e47497f21f64e6d79420dc4c56c1907df22akschulz            /* Create and interconnect local pipes for transport */
1645a60e47497f21f64e6d79420dc4c56c1907df22akschulz            LocalServerSocket serverSock = new LocalServerSocket("com.android.bluetooth.tests.sock");
1655a60e47497f21f64e6d79420dc4c56c1907df22akschulz            LocalSocket clientSock = new LocalSocket();
1665a60e47497f21f64e6d79420dc4c56c1907df22akschulz            LocalSocket acceptSock;
1675a60e47497f21f64e6d79420dc4c56c1907df22akschulz
1685a60e47497f21f64e6d79420dc4c56c1907df22akschulz            clientSock.connect(serverSock.getLocalSocketAddress());
1695a60e47497f21f64e6d79420dc4c56c1907df22akschulz
1705a60e47497f21f64e6d79420dc4c56c1907df22akschulz            acceptSock = serverSock.accept();
1715a60e47497f21f64e6d79420dc4c56c1907df22akschulz
1725a60e47497f21f64e6d79420dc4c56c1907df22akschulz            /* Create the OBEX transport objects to wrap the pipes - enable SRM */
1735a60e47497f21f64e6d79420dc4c56c1907df22akschulz            ObexPipeTransport clientTransport = new ObexPipeTransport(clientSock.getInputStream(),
1745a60e47497f21f64e6d79420dc4c56c1907df22akschulz                    clientSock.getOutputStream(), true);
1755a60e47497f21f64e6d79420dc4c56c1907df22akschulz            ObexPipeTransport serverTransport = new ObexPipeTransport(acceptSock.getInputStream(),
1765a60e47497f21f64e6d79420dc4c56c1907df22akschulz                    acceptSock.getOutputStream(), true);
1775a60e47497f21f64e6d79420dc4c56c1907df22akschulz
1785a60e47497f21f64e6d79420dc4c56c1907df22akschulz            TestSequencer sequencer = createBtPayloadTestSequence(clientTransport, serverTransport);
1795a60e47497f21f64e6d79420dc4c56c1907df22akschulz
1805a60e47497f21f64e6d79420dc4c56c1907df22akschulz            //Debug.startMethodTracing("ObexTrace");
1815a60e47497f21f64e6d79420dc4c56c1907df22akschulz            assertTrue(sequencer.run(mContext));
1825a60e47497f21f64e6d79420dc4c56c1907df22akschulz            //Debug.stopMethodTracing();
1835a60e47497f21f64e6d79420dc4c56c1907df22akschulz
1845a60e47497f21f64e6d79420dc4c56c1907df22akschulz            clientSock.close();
1855a60e47497f21f64e6d79420dc4c56c1907df22akschulz            acceptSock.close();
1865a60e47497f21f64e6d79420dc4c56c1907df22akschulz            serverSock.close();
1875a60e47497f21f64e6d79420dc4c56c1907df22akschulz        } catch (IOException e) {
1885a60e47497f21f64e6d79420dc4c56c1907df22akschulz            Log.e(TAG, "IOException", e);
1895a60e47497f21f64e6d79420dc4c56c1907df22akschulz        }
1905a60e47497f21f64e6d79420dc4c56c1907df22akschulz    }
1915a60e47497f21f64e6d79420dc4c56c1907df22akschulz
192bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    /* Create a sequence of put/get operations with different payload sizes */
193bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    private TestSequencer createBtPayloadTestSequence(ObexTransport clientTransport,
194bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            ObexTransport serverTransport)
195bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            throws IOException {
1965a60e47497f21f64e6d79420dc4c56c1907df22akschulz        TestSequencer sequencer = new TestSequencer(clientTransport, serverTransport, this);
197bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        SeqStep step;
198bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
1995a60e47497f21f64e6d79420dc4c56c1907df22akschulz        step = sequencer.addStep(OPTYPE.CONNECT, sResponseCodeValidator);
2005a60e47497f21f64e6d79420dc4c56c1907df22akschulz        if(false){
201bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
2025a60e47497f21f64e6d79420dc4c56c1907df22akschulz        step = sequencer.addStep(OPTYPE.PUT, sDataValidator);
203bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        step.mParams = defaultParams;
204bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        step.mUseSrm = true;
205bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
2065a60e47497f21f64e6d79420dc4c56c1907df22akschulz        step = sequencer.addStep(OPTYPE.GET, sDataValidator);
207bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        step.mParams = defaultParams;
208bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        step.mUseSrm = true;
2095a60e47497f21f64e6d79420dc4c56c1907df22akschulz
2105a60e47497f21f64e6d79420dc4c56c1907df22akschulz        step = sequencer.addStep(OPTYPE.PUT, sDataValidator);
211bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        step.mParams = throttle100Params;
212bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        step.mUseSrm = true;
213bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
2145a60e47497f21f64e6d79420dc4c56c1907df22akschulz        step = sequencer.addStep(OPTYPE.GET, sDataValidator);
215bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        step.mParams = throttle100Params;
216bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        step.mUseSrm = true;
217bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
218bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        for(int i=0; i<SMALL_OPERATION_COUNT; i++){
2195a60e47497f21f64e6d79420dc4c56c1907df22akschulz            step = sequencer.addStep(OPTYPE.PUT, sDataValidator);
220bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            step.mParams = smallParams;
221bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            step.mUseSrm = true;
222bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
2235a60e47497f21f64e6d79420dc4c56c1907df22akschulz            step = sequencer.addStep(OPTYPE.GET, sDataValidator);
224bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            step.mParams = smallParams;
225bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            step.mUseSrm = true;
226bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
227bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        }
2285a60e47497f21f64e6d79420dc4c56c1907df22akschulz}
229bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
2305a60e47497f21f64e6d79420dc4c56c1907df22akschulz        step = sequencer.addStep(OPTYPE.PUT, sDataValidator);
231bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        step.mParams = hugeParams;
232bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        step.mUseSrm = true;
233bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
2345a60e47497f21f64e6d79420dc4c56c1907df22akschulz        step = sequencer.addStep(OPTYPE.GET, sDataValidator);
235bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        step.mParams = hugeParams;
236bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        step.mUseSrm = true;
2375a60e47497f21f64e6d79420dc4c56c1907df22akschulz        step = sequencer.addStep(OPTYPE.DISCONNECT, sResponseCodeValidator);
238bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
239bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        return sequencer;
240bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    }
241bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
242bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    private TestSequencer createBtConnectTestSequence(ObexTransport clientTransport,
243bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            ObexTransport serverTransport)
244bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            throws IOException {
2455a60e47497f21f64e6d79420dc4c56c1907df22akschulz        TestSequencer sequencer = new TestSequencer(clientTransport, serverTransport, this);
246bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        SeqStep step;
247bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
2485a60e47497f21f64e6d79420dc4c56c1907df22akschulz            step = sequencer.addStep(OPTYPE.CONNECT, sResponseCodeValidator);
249bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
2505a60e47497f21f64e6d79420dc4c56c1907df22akschulz            step = sequencer.addStep(OPTYPE.PUT, sDataValidator);
251bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            step.mParams = smallParams;
252bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            step.mUseSrm = true;
253bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
2545a60e47497f21f64e6d79420dc4c56c1907df22akschulz            step = sequencer.addStep(OPTYPE.GET, sDataValidator);
255bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            step.mParams = smallParams;
256bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            step.mUseSrm = true;
257bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
2585a60e47497f21f64e6d79420dc4c56c1907df22akschulz            step = sequencer.addStep(OPTYPE.DISCONNECT, sResponseCodeValidator);
259bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
260bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        return sequencer;
261bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    }
262bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
2635a60e47497f21f64e6d79420dc4c56c1907df22akschulz
2645a60e47497f21f64e6d79420dc4c56c1907df22akschulz    /**
2655a60e47497f21f64e6d79420dc4c56c1907df22akschulz     * Use this validator to validate operation response codes. E.g. for OBEX CONNECT and
2665a60e47497f21f64e6d79420dc4c56c1907df22akschulz     * DISCONNECT operations.
2675a60e47497f21f64e6d79420dc4c56c1907df22akschulz     * Expects HeaderSet to be valid, and Operation to be null.
2685a60e47497f21f64e6d79420dc4c56c1907df22akschulz     */
2695a60e47497f21f64e6d79420dc4c56c1907df22akschulz    public static ISeqStepValidator getResponsecodevalidator() {
2705a60e47497f21f64e6d79420dc4c56c1907df22akschulz        return sResponseCodeValidator;
2715a60e47497f21f64e6d79420dc4c56c1907df22akschulz    }
2725a60e47497f21f64e6d79420dc4c56c1907df22akschulz
2735a60e47497f21f64e6d79420dc4c56c1907df22akschulz    /**
2745a60e47497f21f64e6d79420dc4c56c1907df22akschulz     * Use this validator to validate (and read/write data) for OBEX PUT and GET operations.
2755a60e47497f21f64e6d79420dc4c56c1907df22akschulz     * Expects Operation to be valid, and HeaderSet to be null.
2765a60e47497f21f64e6d79420dc4c56c1907df22akschulz     */
2775a60e47497f21f64e6d79420dc4c56c1907df22akschulz    public static ISeqStepValidator getDatavalidator() {
2785a60e47497f21f64e6d79420dc4c56c1907df22akschulz        return sDataValidator;
2795a60e47497f21f64e6d79420dc4c56c1907df22akschulz    }
2805a60e47497f21f64e6d79420dc4c56c1907df22akschulz
2815a60e47497f21f64e6d79420dc4c56c1907df22akschulz    /**
2825a60e47497f21f64e6d79420dc4c56c1907df22akschulz     * Use this validator to validate operation response codes. E.g. for OBEX CONNECT and
2835a60e47497f21f64e6d79420dc4c56c1907df22akschulz     * DISCONNECT operations.
2845a60e47497f21f64e6d79420dc4c56c1907df22akschulz     * Expects HeaderSet to be valid, and Operation to be null.
2855a60e47497f21f64e6d79420dc4c56c1907df22akschulz     */
2865a60e47497f21f64e6d79420dc4c56c1907df22akschulz    private static class ResponseCodeValidator implements ISeqStepValidator {
2875a60e47497f21f64e6d79420dc4c56c1907df22akschulz
2885a60e47497f21f64e6d79420dc4c56c1907df22akschulz        protected static boolean validateHeaderSet(HeaderSet headers, HeaderSet expected)
2895a60e47497f21f64e6d79420dc4c56c1907df22akschulz                throws IOException {
2905a60e47497f21f64e6d79420dc4c56c1907df22akschulz            if(headers.getResponseCode() != ResponseCodes.OBEX_HTTP_OK) {
2915a60e47497f21f64e6d79420dc4c56c1907df22akschulz                Log.e(TAG,"Wrong ResponseCode: " + headers.getResponseCode());
2925a60e47497f21f64e6d79420dc4c56c1907df22akschulz                Assert.assertTrue(false);
2935a60e47497f21f64e6d79420dc4c56c1907df22akschulz                return false;
2945a60e47497f21f64e6d79420dc4c56c1907df22akschulz            }
2955a60e47497f21f64e6d79420dc4c56c1907df22akschulz            return true;
2965a60e47497f21f64e6d79420dc4c56c1907df22akschulz        }
2975a60e47497f21f64e6d79420dc4c56c1907df22akschulz
2985a60e47497f21f64e6d79420dc4c56c1907df22akschulz        @Override
2995a60e47497f21f64e6d79420dc4c56c1907df22akschulz        public boolean validate(SeqStep step, HeaderSet response, Operation op)
3005a60e47497f21f64e6d79420dc4c56c1907df22akschulz                throws IOException {
3015a60e47497f21f64e6d79420dc4c56c1907df22akschulz            if(response == null) {
3025a60e47497f21f64e6d79420dc4c56c1907df22akschulz                if(op.getResponseCode() != ResponseCodes.OBEX_HTTP_OK) {
3035a60e47497f21f64e6d79420dc4c56c1907df22akschulz                    Log.e(TAG,"Wrong ResponseCode: " + op.getResponseCode());
3045a60e47497f21f64e6d79420dc4c56c1907df22akschulz                    Assert.assertTrue(false);
3055a60e47497f21f64e6d79420dc4c56c1907df22akschulz                    return false;
3065a60e47497f21f64e6d79420dc4c56c1907df22akschulz                }
3075a60e47497f21f64e6d79420dc4c56c1907df22akschulz                return true;
3085a60e47497f21f64e6d79420dc4c56c1907df22akschulz            }
3095a60e47497f21f64e6d79420dc4c56c1907df22akschulz            return validateHeaderSet(response, step.mResHeaders);
3105a60e47497f21f64e6d79420dc4c56c1907df22akschulz        }
3115a60e47497f21f64e6d79420dc4c56c1907df22akschulz    }
3125a60e47497f21f64e6d79420dc4c56c1907df22akschulz
3135a60e47497f21f64e6d79420dc4c56c1907df22akschulz    /**
3145a60e47497f21f64e6d79420dc4c56c1907df22akschulz     * Use this validator to validate (and read/write data) for OBEX PUT and GET operations.
3155a60e47497f21f64e6d79420dc4c56c1907df22akschulz     * Expects Operation to ve valid, and HeaderSet to be null.
3165a60e47497f21f64e6d79420dc4c56c1907df22akschulz     */
3175a60e47497f21f64e6d79420dc4c56c1907df22akschulz    private static class DataValidator implements ISeqStepValidator {
3185a60e47497f21f64e6d79420dc4c56c1907df22akschulz        @Override
3195a60e47497f21f64e6d79420dc4c56c1907df22akschulz        public boolean validate(SeqStep step, HeaderSet notUsed, Operation op)
3205a60e47497f21f64e6d79420dc4c56c1907df22akschulz        throws IOException {
3215a60e47497f21f64e6d79420dc4c56c1907df22akschulz            Assert.assertNotNull(op);
3225a60e47497f21f64e6d79420dc4c56c1907df22akschulz            if(step.mType == OPTYPE.GET) {
3235a60e47497f21f64e6d79420dc4c56c1907df22akschulz                op.noBodyHeader();
3245a60e47497f21f64e6d79420dc4c56c1907df22akschulz                sDataHandler.readData(op.openDataInputStream(), step.mParams);
3255a60e47497f21f64e6d79420dc4c56c1907df22akschulz            } else if (step.mType == OPTYPE.PUT) {
3265a60e47497f21f64e6d79420dc4c56c1907df22akschulz                sDataHandler.writeData(op.openDataOutputStream(), step.mParams);
3275a60e47497f21f64e6d79420dc4c56c1907df22akschulz            }
3285a60e47497f21f64e6d79420dc4c56c1907df22akschulz            int responseCode = op.getResponseCode();
3295a60e47497f21f64e6d79420dc4c56c1907df22akschulz            Log.i(TAG, "response code: " + responseCode);
3305a60e47497f21f64e6d79420dc4c56c1907df22akschulz            HeaderSet response = op.getReceivedHeader();
3315a60e47497f21f64e6d79420dc4c56c1907df22akschulz            ResponseCodeValidator.validateHeaderSet(response, step.mResHeaders);
3325a60e47497f21f64e6d79420dc4c56c1907df22akschulz            op.close();
3335a60e47497f21f64e6d79420dc4c56c1907df22akschulz            return true;
3345a60e47497f21f64e6d79420dc4c56c1907df22akschulz        }
3355a60e47497f21f64e6d79420dc4c56c1907df22akschulz    }
3365a60e47497f21f64e6d79420dc4c56c1907df22akschulz
337bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    public void testBtServerL2cap() {
338bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        testBtServer(BluetoothSocket.TYPE_L2CAP, false, SequencerType.SEQ_TYPE_PAYLOAD);
339bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    }
340bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
341bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    public void testBtServerRfcomm() {
342bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        testBtServer(BluetoothSocket.TYPE_RFCOMM, false, SequencerType.SEQ_TYPE_PAYLOAD);
343bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    }
344bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
345bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    public void testBtClientL2cap() {
346bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        testBtClient(BluetoothSocket.TYPE_L2CAP, false, SequencerType.SEQ_TYPE_PAYLOAD);
347bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    }
348bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
349bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    public void testBtClientRfcomm() {
350bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        testBtClient(BluetoothSocket.TYPE_RFCOMM, false, SequencerType.SEQ_TYPE_PAYLOAD);
351bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    }
352bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
353bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    public void testBtServerSdpL2cap() {
354bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        testBtServer(BluetoothSocket.TYPE_L2CAP, true, SequencerType.SEQ_TYPE_PAYLOAD);
355bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    }
356bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
357bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    public void testBtServerSdpRfcomm() {
358bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        testBtServer(BluetoothSocket.TYPE_RFCOMM, true, SequencerType.SEQ_TYPE_PAYLOAD);
359bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    }
360bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
361bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    public void testBtClientSdpL2cap() {
362bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        testBtClient(BluetoothSocket.TYPE_L2CAP, true, SequencerType.SEQ_TYPE_PAYLOAD);
363bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    }
364bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
365bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    public void testBtClientSdpRfcomm() {
366bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        testBtClient(BluetoothSocket.TYPE_RFCOMM, true, SequencerType.SEQ_TYPE_PAYLOAD);
367bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    }
368bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
369bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    public void testBtServerConnectL2cap() {
370bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        for(int i=0; i<CONNECT_OPERATION_COUNT; i++){
371bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            Log.i(TAG, "Starting iteration " + i);
372bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            testBtServer(BluetoothSocket.TYPE_L2CAP, true,
373bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                    SequencerType.SEQ_TYPE_CONNECT_DISCONNECT);
374bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            try {
375bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                Thread.sleep(50);
376bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            } catch (InterruptedException e) {
377bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                Log.e(TAG,"Exception while waiting...",e);
378bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            }
379bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        }
380bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    }
381bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
382bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    public void testBtClientConnectL2cap() {
383bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        for(int i=0; i<CONNECT_OPERATION_COUNT; i++){
384bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            Log.i(TAG, "Starting iteration " + i);
385bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            testBtClient(BluetoothSocket.TYPE_L2CAP, true,
386bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                    SequencerType.SEQ_TYPE_CONNECT_DISCONNECT);
387bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            try {
388bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                // We give the server 100ms to allow adding SDP record
3895a60e47497f21f64e6d79420dc4c56c1907df22akschulz                Thread.sleep(150);
390bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            } catch (InterruptedException e) {
391bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                Log.e(TAG,"Exception while waiting...",e);
392bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            }
393bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        }
394bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    }
395bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
396bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    public void testBtServerConnectRfcomm() {
397bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        for(int i=0; i<CONNECT_OPERATION_COUNT; i++){
398bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            Log.i(TAG, "Starting iteration " + i);
399bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            testBtServer(BluetoothSocket.TYPE_RFCOMM, true,
400bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                    SequencerType.SEQ_TYPE_CONNECT_DISCONNECT);
401bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            try {
402bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                Thread.sleep(50);
403bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            } catch (InterruptedException e) {
404bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                Log.e(TAG,"Exception while waiting...",e);
405bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            }
406bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        }
407bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    }
408bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
409bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    public void testBtClientConnectRfcomm() {
410bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        for(int i=0; i<CONNECT_OPERATION_COUNT; i++){
411bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            Log.i(TAG, "Starting iteration " + i);
412bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            testBtClient(BluetoothSocket.TYPE_RFCOMM, true,
413bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                    SequencerType.SEQ_TYPE_CONNECT_DISCONNECT);
414bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            try {
415bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                // We give the server 100ms to allow adding SDP record
4165a60e47497f21f64e6d79420dc4c56c1907df22akschulz                Thread.sleep(250);
417bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            } catch (InterruptedException e) {
418bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                Log.e(TAG,"Exception while waiting...",e);
419bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            }
420bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        }
421bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    }
422bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
423bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    /**
424bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * Create a serverSocket
425bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * @param type
426bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * @param useSdp
427bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * @return
428bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * @throws IOException
429bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     */
430bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    public static BluetoothServerSocket createServerSocket(int type, boolean useSdp)
431bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            throws IOException {
432bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        int rfcommChannel = -1;
433bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        int l2capPsm = -1;
434bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
435bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        BluetoothAdapter bt = BluetoothAdapter.getDefaultAdapter();
436bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        if(bt == null) {
437bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            Log.e(TAG,"No Bluetooth Device!");
438bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            assertTrue(false);
439bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        }
4405a60e47497f21f64e6d79420dc4c56c1907df22akschulz        BluetoothTestUtils.enableBt(bt);
441bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        BluetoothServerSocket serverSocket=null;
442bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        if(type == BluetoothSocket.TYPE_L2CAP) {
443bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            if(useSdp == true) {
444bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                serverSocket = bt.listenUsingL2capOn(
445bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                        BluetoothAdapter.SOCKET_CHANNEL_AUTO_STATIC_NO_SDP);
4465a60e47497f21f64e6d79420dc4c56c1907df22akschulz            } else {
4475a60e47497f21f64e6d79420dc4c56c1907df22akschulz                serverSocket = bt.listenUsingL2capOn(L2CAP_PSM);
448bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            }
449bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            l2capPsm = serverSocket.getChannel();
4505a60e47497f21f64e6d79420dc4c56c1907df22akschulz            Log.d(TAG, "L2CAP createde, PSM: " + l2capPsm);
451bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        } else if(type == BluetoothSocket.TYPE_RFCOMM) {
452bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            if(useSdp == true) {
453bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                serverSocket = bt.listenUsingInsecureRfcommOn(
454bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                        BluetoothAdapter.SOCKET_CHANNEL_AUTO_STATIC_NO_SDP);
455bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            } else {
456bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                serverSocket = bt.listenUsingInsecureRfcommOn(RFCOMM_CHANNEL);
457bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            }
458bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            rfcommChannel = serverSocket.getChannel();
4595a60e47497f21f64e6d79420dc4c56c1907df22akschulz            Log.d(TAG, "RFCOMM createde, Channel: " + rfcommChannel);
460bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        } else {
461bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            fail("Invalid transport type!");
462bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        }
463bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        if(useSdp == true) {
4645a60e47497f21f64e6d79420dc4c56c1907df22akschulz            /* We use the MAP service record to be able to set rfcomm and l2cap channels */
465bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            // TODO: We need to free this
4665a60e47497f21f64e6d79420dc4c56c1907df22akschulz            if(sSdpHandle >= 0) {
4675a60e47497f21f64e6d79420dc4c56c1907df22akschulz                SdpManager.getDefaultManager().removeSdpRecord(sSdpHandle);
468bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            }
4695a60e47497f21f64e6d79420dc4c56c1907df22akschulz            Log.d(TAG, "Creating record with rfcomm channel: " + rfcommChannel +
4705a60e47497f21f64e6d79420dc4c56c1907df22akschulz                    " and l2cap channel: " + l2capPsm);
4715a60e47497f21f64e6d79420dc4c56c1907df22akschulz            sSdpHandle = SdpManager.getDefaultManager().createMapMasRecord(SDP_SERVER_NAME,
4725a60e47497f21f64e6d79420dc4c56c1907df22akschulz                    SDP_MAS_ID, rfcommChannel, l2capPsm,
4735a60e47497f21f64e6d79420dc4c56c1907df22akschulz                    SDP_VERSION, SDP_MSG_TYPES, (int)(SDP_FEATURES & 0xffffffff));
4745a60e47497f21f64e6d79420dc4c56c1907df22akschulz        } else {
4755a60e47497f21f64e6d79420dc4c56c1907df22akschulz            Log.d(TAG, "SKIP creation of record with rfcomm channel: " + rfcommChannel +
4765a60e47497f21f64e6d79420dc4c56c1907df22akschulz                    " and l2cap channel: " + l2capPsm);
477bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        }
478bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        return serverSocket;
479bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    }
480bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
481bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    public static void removeSdp() {
482bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        if(sSdpHandle > 0) {
483bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            SdpManager.getDefaultManager().removeSdpRecord(sSdpHandle);
484bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            sSdpHandle = -1;
485bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        }
486bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    }
487bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
488bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    /**
489bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * Server side of a two device Bluetooth test of OBEX
490bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     */
491bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    private void testBtServer(int type, boolean useSdp, SequencerType sequencerType) {
492bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        mContext = this.getContext();
4935a60e47497f21f64e6d79420dc4c56c1907df22akschulz        Log.d(TAG,"Starting BT Server...");
494bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
495bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        if(TRACE) Debug.startMethodTracing("ServerSide");
496bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        try {
497bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            BluetoothServerSocket serverSocket=createServerSocket(type, useSdp);
498bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
499bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            Log.i(TAG, "Waiting for client to connect");
500bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            BluetoothSocket socket = serverSocket.accept();
501bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            Log.i(TAG, "Client connected");
502bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
503bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            BluetoothObexTransport serverTransport = new BluetoothObexTransport(socket);
504bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            TestSequencer sequencer = null;
505bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            switch(sequencerType) {
506bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            case SEQ_TYPE_CONNECT_DISCONNECT:
507bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                sequencer = createBtConnectTestSequence(null, serverTransport);
508bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                break;
509bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            case SEQ_TYPE_PAYLOAD:
510bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                sequencer = createBtPayloadTestSequence(null, serverTransport);
511bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                break;
512bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            default:
513bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                fail("Invalid sequencer type");
514bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                break;
515bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
516bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            }
517bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            //Debug.startMethodTracing("ObexTrace");
5185a60e47497f21f64e6d79420dc4c56c1907df22akschulz            assertTrue(sequencer.run(mContext));
519bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            //Debug.stopMethodTracing();
520bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            // Same as below... serverTransport.close();
521bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            // This is done by the obex server socket.close();
522bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            serverSocket.close();
523bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            removeSdp();
524bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            sequencer.shutdown();
525bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        } catch (IOException e) {
526bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            Log.e(TAG, "IOException", e);
527bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        }
528bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        if(TRACE) Debug.stopMethodTracing();
529bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        if(DELAY_PASS_30_SEC) {
530bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            Log.i(TAG, "\n\n\nTest done - please fetch logs within 30 seconds...\n\n\n");
531bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            try {
532bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                Thread.sleep(30000);
533bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            } catch (InterruptedException e) {}
534bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        }
535bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        Log.i(TAG, "Test done.");
536bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    }
537bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
538bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    /**
539bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * Enable Bluetooth and connect to a server socket
540bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * @param type
541bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * @param useSdp
542bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * @param context
543bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * @return
544bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * @throws IOException
545bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     */
546bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    static public BluetoothSocket connectClientSocket(int type, boolean useSdp, Context context)
547bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            throws IOException {
548bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        int rfcommChannel = RFCOMM_CHANNEL;
549bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        int l2capPsm = L2CAP_PSM;
550bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
551bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        BluetoothAdapter bt = BluetoothAdapter.getDefaultAdapter();
552bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        if(bt == null) {
553bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            Log.e(TAG,"No Bluetooth Device!");
554bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            assertTrue(false);
555bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        }
5565a60e47497f21f64e6d79420dc4c56c1907df22akschulz        BluetoothTestUtils.enableBt(bt);
557bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        BluetoothDevice serverDevice = bt.getRemoteDevice(SERVER_ADDRESS);
558bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
559bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        if(useSdp == true) {
560bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            SdpMasRecord record = clientAwaitSdp(serverDevice, context);
561bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            rfcommChannel = record.getRfcommCannelNumber();
562bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            l2capPsm = record.getL2capPsm();
563bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        }
564bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
565bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        BluetoothSocket socket = null;
566bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        if(type == BluetoothSocket.TYPE_L2CAP) {
567bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            socket = serverDevice.createL2capSocket(l2capPsm);
568bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        } else if(type == BluetoothSocket.TYPE_RFCOMM) {
569bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            socket = serverDevice.createRfcommSocket(rfcommChannel);
570bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        } else {
571bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            fail("Invalid transport type!");
572bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        }
573bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
574bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        socket.connect();
575bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
576bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        return socket;
577bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    }
578bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
579bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    /**
580bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * Test that a connection can be established.
581bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     */
582bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    private void testBtClient(int type, boolean useSdp, SequencerType sequencerType) {
583bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        mContext = this.getContext();
584bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        mChannelType = type;
585bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        BluetoothSocket socket = null;
586bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        System.out.println("Starting BT Client...");
587bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        if(TRACE) Debug.startMethodTracing("ClientSide");
588bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        try {
589bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            socket = connectClientSocket(type, useSdp, mContext);
590bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
591bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            BluetoothObexTransport clientTransport = new BluetoothObexTransport(socket);
592bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
593bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            TestSequencer sequencer = null;
594bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            switch(sequencerType) {
595bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            case SEQ_TYPE_CONNECT_DISCONNECT:
596bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                sequencer = createBtConnectTestSequence(clientTransport, null);
597bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                break;
598bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            case SEQ_TYPE_PAYLOAD:
599bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                sequencer = createBtPayloadTestSequence(clientTransport, null);
600bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                break;
601bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            default:
602bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                fail("Invalid test type");
603bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                break;
604bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
605bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            }
606bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            //Debug.startMethodTracing("ObexTrace");
6075a60e47497f21f64e6d79420dc4c56c1907df22akschulz            assertTrue(sequencer.run(mContext));
608bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            //Debug.stopMethodTracing();
6095a60e47497f21f64e6d79420dc4c56c1907df22akschulz            socket.close(); // Only the streams are closed by the obex client
610bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            sequencer.shutdown();
611bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
612bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        } catch (IOException e) {
613bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            Log.e(TAG, "IOException", e);
614bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        }
615bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        if(TRACE) Debug.stopMethodTracing();
616bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        if(DELAY_PASS_30_SEC) {
617bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            Log.i(TAG, "\n\n\nTest done - please fetch logs within 30 seconds...\n\n\n");
618bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            try {
619bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                Thread.sleep(30000);
620bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            } catch (InterruptedException e) {}
621bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        }
622bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        Log.i(TAG, "Test done.");
623bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    }
624bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
625bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    /* Using an anonymous class is not efficient, but keeps a tight code structure. */
626bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    static class SdpBroadcastReceiver extends BroadcastReceiver {
627bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        private SdpMasRecord mMasRecord; /* A non-optimal way of setting an object reference from
628bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                                            a anonymous class. */
629bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        final CountDownLatch mLatch;
630bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        public SdpBroadcastReceiver(CountDownLatch latch) {
631bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            mLatch = latch;
632bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        }
633bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
634bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        SdpMasRecord getMasRecord() {
635bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            return mMasRecord;
636bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        }
637bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
638bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        @Override
639bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        public void onReceive(Context context, Intent intent) {
640bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            Log.d(TAG, "onReceive");
641bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            String action = intent.getAction();
642bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            if (action.equals(BluetoothDevice.ACTION_SDP_RECORD)){
643bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                Log.v(TAG, "Received ACTION_SDP_RECORD.");
644bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                ParcelUuid uuid = intent.getParcelableExtra(BluetoothDevice.EXTRA_UUID);
645bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                Log.v(TAG, "Received UUID: " + uuid.toString());
646bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                Log.v(TAG, "existing UUID: " + SDP_UUID_OBEX_MAS.toString());
647bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                if(uuid.toString().equals(SDP_UUID_OBEX_MAS.toString())) {
648bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                    assertEquals(SDP_UUID_OBEX_MAS.toString(), uuid.toString());
649bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                    Log.v(TAG, " -> MAS UUID in result.");
650bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                    SdpMasRecord record = intent.getParcelableExtra(
651bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                            BluetoothDevice.EXTRA_SDP_RECORD);
652bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                    assertNotNull(record);
653bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                    Log.v(TAG, " -> record: "+record);
654bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                    if(record.getServiceName().equals(SDP_SERVER_NAME)) {
655bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
656bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                        assertEquals(((long)record.getSupportedFeatures())
657bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                                &0xffffffffL, SDP_FEATURES);
658bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
659bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                        assertEquals(record.getSupportedMessageTypes(), SDP_MSG_TYPES);
660bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
661bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                        assertEquals(record.getProfileVersion(), SDP_VERSION);
662bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
663bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                        assertEquals(record.getServiceName(), SDP_SERVER_NAME);
664bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
665bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                        assertEquals(record.getMasInstanceId(), SDP_MAS_ID);
666bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
667bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                        int status = intent.getIntExtra(BluetoothDevice.EXTRA_SDP_SEARCH_STATUS,
668bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                                -1);
669bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                        Log.v(TAG, " -> status: "+status);
670bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                        mMasRecord = record;
671bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                        mLatch.countDown();
672bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                    } else {
673bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                        Log.i(TAG, "Wrong service name (" + record.getServiceName()
674bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                                + ") received, still waiting...");
675bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                    }
676bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                } else {
677bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                    Log.i(TAG, "Wrong UUID received, still waiting...");
678bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                }
679bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            } else {
680bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                fail("Unexpected intent received???");
681bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            }
682bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        }
683bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    };
684bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
685bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
686bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    private static SdpMasRecord clientAwaitSdp(BluetoothDevice serverDevice, Context context) {
687bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        IntentFilter filter = new IntentFilter();
688bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        filter.addAction(BluetoothDevice.ACTION_SDP_RECORD);
689bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        final CountDownLatch latch = new CountDownLatch(1);
690bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        SdpBroadcastReceiver broadcastReceiver = new SdpBroadcastReceiver(latch);
691bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
692bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        context.registerReceiver(broadcastReceiver, filter);
693bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
694bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        serverDevice.sdpSearch(SDP_UUID_OBEX_MAS);
695bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        boolean waiting = true;
696bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        while(waiting == true) {
697bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            try {
698bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                Log.i(TAG, "SDP Search requested - awaiting result...");
699bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                latch.await();
700bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                Log.i(TAG, "SDP Search reresult received - continueing.");
701bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                waiting = false;
702bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            } catch (InterruptedException e) {
703bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                Log.w(TAG, "Interrupted witle waiting - keep waiting.", e);
704bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                waiting = true;
705bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            }
706bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        }
707bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        context.unregisterReceiver(broadcastReceiver);
708bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        return broadcastReceiver.getMasRecord();
709bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    }
710bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
7115a60e47497f21f64e6d79420dc4c56c1907df22akschulz    @Override
7125a60e47497f21f64e6d79420dc4c56c1907df22akschulz    public ServerRequestHandler getObexServer(ArrayList<SeqStep> sequence,
7135a60e47497f21f64e6d79420dc4c56c1907df22akschulz            CountDownLatch stopLatch) {
7145a60e47497f21f64e6d79420dc4c56c1907df22akschulz        return new ObexTestServer(sequence, stopLatch);
715bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    }
716bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
717bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
718bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
7195a60e47497f21f64e6d79420dc4c56c1907df22akschulz}
720bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
721