• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.android.bluetooth.tests;
2 
3 import java.io.IOException;
4 import java.util.ArrayList;
5 import java.util.Arrays;
6 import java.util.concurrent.CountDownLatch;
7 
8 import javax.obex.HeaderSet;
9 import javax.obex.Operation;
10 import javax.obex.ServerRequestHandler;
11 
12 import junit.framework.Assert;
13 import android.annotation.TargetApi;
14 import android.bluetooth.BluetoothServerSocket;
15 import android.bluetooth.BluetoothSocket;
16 import android.net.LocalServerSocket;
17 import android.net.LocalSocket;
18 import android.os.Build;
19 import android.os.RemoteException;
20 import android.test.AndroidTestCase;
21 import android.util.Log;
22 
23 import com.android.bluetooth.BluetoothObexTransport;
24 import com.android.bluetooth.tests.TestSequencer.OPTYPE;
25 
26 @TargetApi(Build.VERSION_CODES.KITKAT)
27 public class MapObexLevelTest extends AndroidTestCase implements ITestSequenceConfigurator {
28     protected static String TAG = "MapObexLevelTest";
29     protected static final boolean D = true;
30     protected static final boolean TRACE = false;
31     protected static final boolean DELAY_PASS_30_SEC = true;
32 
33     // 128 bit UUID for MAP MAS
34     static final byte[] MAS_TARGET = new byte[] {
35              (byte)0xBB, (byte)0x58, (byte)0x2B, (byte)0x40,
36              (byte)0x42, (byte)0x0C, (byte)0x11, (byte)0xDB,
37              (byte)0xB0, (byte)0xDE, (byte)0x08, (byte)0x00,
38              (byte)0x20, (byte)0x0C, (byte)0x9A, (byte)0x66
39              };
40 
41     // 128 bit UUID for MAP MNS
42     static final byte[] MNS_TARGET = new byte[] {
43              (byte)0xBB, (byte)0x58, (byte)0x2B, (byte)0x41,
44              (byte)0x42, (byte)0x0C, (byte)0x11, (byte)0xDB,
45              (byte)0xB0, (byte)0xDE, (byte)0x08, (byte)0x00,
46              (byte)0x20, (byte)0x0C, (byte)0x9A, (byte)0x66
47              };
48 
49     /* Message types */
50     static final String TYPE_GET_FOLDER_LISTING              = "x-obex/folder-listing";
51     static final String TYPE_GET_MESSAGE_LISTING             = "x-bt/MAP-msg-listing";
52     static final String TYPE_GET_CONVO_LISTING               = "x-bt/MAP-convo-listing";
53     static final String TYPE_MESSAGE                         = "x-bt/message";
54     static final String TYPE_SET_MESSAGE_STATUS              = "x-bt/messageStatus";
55     static final String TYPE_SET_NOTIFICATION_REGISTRATION   = "x-bt/MAP-NotificationRegistration";
56     static final String TYPE_MESSAGE_UPDATE                  = "x-bt/MAP-messageUpdate";
57     static final String TYPE_GET_MAS_INSTANCE_INFORMATION    = "x-bt/MASInstanceInformation";
58 
testFolder()59     public void testFolder() {
60         testLocalSockets(new buildFolderTestSeq());
61     }
62 
testFolderServer()63     public void testFolderServer() {
64         testServer(new buildFolderTestSeq());
65     }
66 
testFolderClient()67     public void testFolderClient() {
68         testClient(new buildFolderTestSeq());
69     }
70 
71     protected class buildFolderTestSeq implements ITestSequenceBuilder {
72         @Override
build(TestSequencer sequencer)73         public void build(TestSequencer sequencer) {
74             addConnectStep(sequencer);
75 
76             MapStepsFolder.addGoToMsgFolderSteps(sequencer);
77 
78             // MAP DISCONNECT Step
79             addDisconnectStep(sequencer);
80         }
81     }
82 
83 
testConvo()84     public void testConvo() {
85         testLocalSockets(new buildConvoTestSeq());
86     }
87 
testConvoServer()88     public void testConvoServer() {
89         testServer(new buildConvoTestSeq());
90     }
91 
testConvoClient()92     public void testConvoClient() {
93         testClient(new buildConvoTestSeq());
94     }
95 
96     class buildConvoTestSeq implements ITestSequenceBuilder {
97         @Override
build(TestSequencer sequencer)98         public void build(TestSequencer sequencer) {
99             addConnectStep(sequencer);
100 
101             MapStepsFolder.addGoToMsgFolderSteps(sequencer);
102 
103             MapStepsConvo.addConvoListingSteps(sequencer);
104 
105             // MAP DISCONNECT Step
106             addDisconnectStep(sequencer);
107         }
108     }
109 
110     /**
111      * Run the test sequence using a local socket on a single device.
112      * Throughput around 4000 kbyte/s - with a larger OBEX package size.
113      *
114      * Downside: Unable to get a BT-snoop file...
115      */
testLocalSockets(ITestSequenceBuilder builder)116     protected void testLocalSockets(ITestSequenceBuilder builder) {
117         mContext = this.getContext();
118         MapTestData.init(mContext);
119         Log.i(TAG,"Setting up sockets...");
120 
121         try {
122             /* Create and interconnect local pipes for transport */
123             LocalServerSocket serverSock = new LocalServerSocket("com.android.bluetooth.tests.sock");
124             LocalSocket clientSock = new LocalSocket();
125             LocalSocket acceptSock;
126 
127             clientSock.connect(serverSock.getLocalSocketAddress());
128 
129             acceptSock = serverSock.accept();
130 
131             /* Create the OBEX transport objects to wrap the pipes - enable SRM */
132             ObexPipeTransport clientTransport = new ObexPipeTransport(clientSock.getInputStream(),
133                     clientSock.getOutputStream(), true);
134             ObexPipeTransport serverTransport = new ObexPipeTransport(acceptSock.getInputStream(),
135                     acceptSock.getOutputStream(), true);
136 
137             TestSequencer sequencer  = new TestSequencer(clientTransport, serverTransport, this);
138 
139             builder.build(sequencer);
140 
141             //Debug.startMethodTracing("ObexTrace");
142             assertTrue(sequencer.run(mContext));
143             //Debug.stopMethodTracing();
144 
145             clientSock.close();
146             acceptSock.close();
147             serverSock.close();
148         } catch (IOException e) {
149             Log.e(TAG, "IOException", e);
150         }
151     }
152 
153     /**
154      * Server side of a dual device test using a Bluetooth Socket.
155      * Enables the possibility to get a BT-snoop file.
156      * If you need the btsnoop from the device which completes the test with success
157      * you need to add a delay after the test ends, and fetch the file before this delay
158      * expires. When the test completes, the Bluetooth subsystem will be restarted, causing
159      * a new bt-snoop to overwrite the one used in test.
160      */
testServer(ITestSequenceBuilder builder)161     public void testServer(ITestSequenceBuilder builder) {
162         mContext = this.getContext();
163         MapTestData.init(mContext);
164         Log.i(TAG,"Setting up sockets...");
165 
166         try {
167             /* This will turn on BT and create a server socket on which accept can be called. */
168             BluetoothServerSocket serverSocket=ObexTest.createServerSocket(BluetoothSocket.TYPE_L2CAP, true);
169 
170             Log.i(TAG, "Waiting for client to connect...");
171             BluetoothSocket socket = serverSocket.accept();
172             Log.i(TAG, "Client connected...");
173 
174             BluetoothObexTransport serverTransport = new BluetoothObexTransport(socket);
175 
176             TestSequencer sequencer  = new TestSequencer(null, serverTransport, this);
177 
178             builder.build(sequencer);
179 
180             //Debug.startMethodTracing("ObexTrace");
181             assertTrue(sequencer.run(mContext));
182             //Debug.stopMethodTracing();
183 
184             serverSocket.close();
185             socket.close();
186         } catch (IOException e) {
187             Log.e(TAG, "IOException", e);
188         }
189         if(DELAY_PASS_30_SEC) {
190             Log.i(TAG, "\n\n\nTest done - please fetch logs within 30 seconds...\n\n\n");
191             try {
192                 Thread.sleep(30000);
193             } catch (InterruptedException e) {}
194         }
195     }
196 
197     /**
198      * Server side of a dual device test using a Bluetooth Socket.
199      * Enables the possibility to get a BT-snoop file.
200      * If you need the btsnoop from the device which completes the test with success
201      * you need to add a delay after the test ends, and fetch the file before this delay
202      * expires. When the test completes, the Bluetooth subsystem will be restarted, causing
203      * a new bt-snoop to overwrite the one used in test.
204      */
testClient(ITestSequenceBuilder builder)205     public void testClient(ITestSequenceBuilder builder) {
206         mContext = this.getContext();
207         MapTestData.init(mContext);
208         Log.i(TAG, "Setting up sockets...");
209 
210         try {
211             /* This will turn on BT and connect */
212             BluetoothSocket clientSock =
213                     ObexTest.connectClientSocket(BluetoothSocket.TYPE_L2CAP, true, mContext);
214 
215             BluetoothObexTransport clientTransport = new BluetoothObexTransport(clientSock);
216 
217             TestSequencer sequencer  = new TestSequencer(clientTransport, null, this);
218 
219             builder.build(sequencer);
220 
221             //Debug.startMethodTracing("ObexTrace");
222             assertTrue(sequencer.run(mContext));
223             //Debug.stopMethodTracing();
224 
225             clientSock.close();
226         } catch (IOException e) {
227             Log.e(TAG, "IOException", e);
228         }
229         if(DELAY_PASS_30_SEC) {
230             Log.i(TAG, "\n\n\nTest done - please fetch logs within 30 seconds...\n\n\n");
231             try {
232                 Thread.sleep(30000);
233             } catch (InterruptedException e) {}
234         }
235     }
236 
addConnectStep(TestSequencer sequencer)237     protected void addConnectStep(TestSequencer sequencer) {
238         SeqStep step;
239 
240         // MAP CONNECT Step
241         step = sequencer.addStep(OPTYPE.CONNECT, null);
242         HeaderSet hs = new HeaderSet();
243         hs.setHeader(HeaderSet.TARGET, MAS_TARGET);
244         step.mReqHeaders = hs;
245         step.mValidator = new MapConnectValidator();
246         //step.mServerPreAction = new MapAddSmsMessages(); // could take in parameters
247     }
248 
addDisconnectStep(TestSequencer sequencer)249     protected void addDisconnectStep(TestSequencer sequencer) {
250         sequencer.addStep(OPTYPE.DISCONNECT, ObexTest.getResponsecodevalidator());
251     }
252 
253     /* Functions to validate results */
254 
255     private class MapConnectValidator implements ISeqStepValidator {
256         @Override
validate(SeqStep step, HeaderSet response, Operation notUsed)257         public boolean validate(SeqStep step, HeaderSet response, Operation notUsed)
258                 throws IOException {
259             Assert.assertNotNull(response);
260             byte[] who = (byte[])response.getHeader(HeaderSet.WHO);
261             Assert.assertNotNull(who);
262             Assert.assertTrue(Arrays.equals(who, MAS_TARGET));
263             Assert.assertNotNull(response.getHeader(HeaderSet.CONNECTION_ID));
264             return true;
265         }
266     }
267 
268     /**
269      * This is the function creating the Obex Server to be used in this class.
270      * Here we use a mocked version of the MapObexServer class
271      */
272     @Override
getObexServer(ArrayList<SeqStep> sequence, CountDownLatch stopLatch)273     public ServerRequestHandler getObexServer(ArrayList<SeqStep> sequence,
274             CountDownLatch stopLatch) {
275         try {
276             return new MapObexTestServer(mContext, sequence, stopLatch);
277         } catch (RemoteException e) {
278             Log.e(TAG, "exception", e);
279             fail("Unable to create MapObexTestServer");
280         }
281         return null;
282     }
283 
284 
285 }
286 
287