blob: fb5de24bd7c78077c78228b75151d3339855fa72 [file] [log] [blame]
package com.android.bluetooth.tests;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.concurrent.CountDownLatch;
import javax.obex.HeaderSet;
import javax.obex.Operation;
import javax.obex.ServerRequestHandler;
import junit.framework.Assert;
import android.annotation.TargetApi;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.net.LocalServerSocket;
import android.net.LocalSocket;
import android.os.Build;
import android.os.RemoteException;
import android.test.AndroidTestCase;
import android.util.Log;
import com.android.bluetooth.BluetoothObexTransport;
import com.android.bluetooth.tests.TestSequencer.OPTYPE;
@TargetApi(Build.VERSION_CODES.KITKAT)
public class MapObexLevelTest extends AndroidTestCase implements ITestSequenceConfigurator {
protected static String TAG = "MapObexLevelTest";
protected static final boolean D = true;
protected static final boolean TRACE = false;
protected static final boolean DELAY_PASS_30_SEC = true;
// 128 bit UUID for MAP MAS
static final byte[] MAS_TARGET = new byte[] {
(byte)0xBB, (byte)0x58, (byte)0x2B, (byte)0x40,
(byte)0x42, (byte)0x0C, (byte)0x11, (byte)0xDB,
(byte)0xB0, (byte)0xDE, (byte)0x08, (byte)0x00,
(byte)0x20, (byte)0x0C, (byte)0x9A, (byte)0x66
};
// 128 bit UUID for MAP MNS
static final byte[] MNS_TARGET = new byte[] {
(byte)0xBB, (byte)0x58, (byte)0x2B, (byte)0x41,
(byte)0x42, (byte)0x0C, (byte)0x11, (byte)0xDB,
(byte)0xB0, (byte)0xDE, (byte)0x08, (byte)0x00,
(byte)0x20, (byte)0x0C, (byte)0x9A, (byte)0x66
};
/* Message types */
static final String TYPE_GET_FOLDER_LISTING = "x-obex/folder-listing";
static final String TYPE_GET_MESSAGE_LISTING = "x-bt/MAP-msg-listing";
static final String TYPE_GET_CONVO_LISTING = "x-bt/MAP-convo-listing";
static final String TYPE_MESSAGE = "x-bt/message";
static final String TYPE_SET_MESSAGE_STATUS = "x-bt/messageStatus";
static final String TYPE_SET_NOTIFICATION_REGISTRATION = "x-bt/MAP-NotificationRegistration";
static final String TYPE_MESSAGE_UPDATE = "x-bt/MAP-messageUpdate";
static final String TYPE_GET_MAS_INSTANCE_INFORMATION = "x-bt/MASInstanceInformation";
public void testFolder() {
testLocalSockets(new buildFolderTestSeq());
}
public void testFolderServer() {
testServer(new buildFolderTestSeq());
}
public void testFolderClient() {
testClient(new buildFolderTestSeq());
}
protected class buildFolderTestSeq implements ITestSequenceBuilder {
@Override
public void build(TestSequencer sequencer) {
addConnectStep(sequencer);
MapStepsFolder.addGoToMsgFolderSteps(sequencer);
// MAP DISCONNECT Step
addDisconnectStep(sequencer);
}
}
public void testConvo() {
testLocalSockets(new buildConvoTestSeq());
}
public void testConvoServer() {
testServer(new buildConvoTestSeq());
}
public void testConvoClient() {
testClient(new buildConvoTestSeq());
}
class buildConvoTestSeq implements ITestSequenceBuilder {
@Override
public void build(TestSequencer sequencer) {
addConnectStep(sequencer);
MapStepsFolder.addGoToMsgFolderSteps(sequencer);
MapStepsConvo.addConvoListingSteps(sequencer);
// MAP DISCONNECT Step
addDisconnectStep(sequencer);
}
}
/**
* Run the test sequence using a local socket on a single device.
* Throughput around 4000 kbyte/s - with a larger OBEX package size.
*
* Downside: Unable to get a BT-snoop file...
*/
protected void testLocalSockets(ITestSequenceBuilder builder) {
mContext = this.getContext();
MapTestData.init(mContext);
Log.i(TAG,"Setting up sockets...");
try {
/* Create and interconnect local pipes for transport */
LocalServerSocket serverSock = new LocalServerSocket("com.android.bluetooth.tests.sock");
LocalSocket clientSock = new LocalSocket();
LocalSocket acceptSock;
clientSock.connect(serverSock.getLocalSocketAddress());
acceptSock = serverSock.accept();
/* Create the OBEX transport objects to wrap the pipes - enable SRM */
ObexPipeTransport clientTransport = new ObexPipeTransport(clientSock.getInputStream(),
clientSock.getOutputStream(), true);
ObexPipeTransport serverTransport = new ObexPipeTransport(acceptSock.getInputStream(),
acceptSock.getOutputStream(), true);
TestSequencer sequencer = new TestSequencer(clientTransport, serverTransport, this);
builder.build(sequencer);
//Debug.startMethodTracing("ObexTrace");
assertTrue(sequencer.run(mContext));
//Debug.stopMethodTracing();
clientSock.close();
acceptSock.close();
serverSock.close();
} catch (IOException e) {
Log.e(TAG, "IOException", e);
}
}
/**
* Server side of a dual device test using a Bluetooth Socket.
* Enables the possibility to get a BT-snoop file.
* If you need the btsnoop from the device which completes the test with success
* you need to add a delay after the test ends, and fetch the file before this delay
* expires. When the test completes, the Bluetooth subsystem will be restarted, causing
* a new bt-snoop to overwrite the one used in test.
*/
public void testServer(ITestSequenceBuilder builder) {
mContext = this.getContext();
MapTestData.init(mContext);
Log.i(TAG,"Setting up sockets...");
try {
/* This will turn on BT and create a server socket on which accept can be called. */
BluetoothServerSocket serverSocket=ObexTest.createServerSocket(BluetoothSocket.TYPE_L2CAP, true);
Log.i(TAG, "Waiting for client to connect...");
BluetoothSocket socket = serverSocket.accept();
Log.i(TAG, "Client connected...");
BluetoothObexTransport serverTransport = new BluetoothObexTransport(socket);
TestSequencer sequencer = new TestSequencer(null, serverTransport, this);
builder.build(sequencer);
//Debug.startMethodTracing("ObexTrace");
assertTrue(sequencer.run(mContext));
//Debug.stopMethodTracing();
serverSocket.close();
socket.close();
} catch (IOException e) {
Log.e(TAG, "IOException", e);
}
if(DELAY_PASS_30_SEC) {
Log.i(TAG, "\n\n\nTest done - please fetch logs within 30 seconds...\n\n\n");
try {
Thread.sleep(30000);
} catch (InterruptedException e) {}
}
}
/**
* Server side of a dual device test using a Bluetooth Socket.
* Enables the possibility to get a BT-snoop file.
* If you need the btsnoop from the device which completes the test with success
* you need to add a delay after the test ends, and fetch the file before this delay
* expires. When the test completes, the Bluetooth subsystem will be restarted, causing
* a new bt-snoop to overwrite the one used in test.
*/
public void testClient(ITestSequenceBuilder builder) {
mContext = this.getContext();
MapTestData.init(mContext);
Log.i(TAG, "Setting up sockets...");
try {
/* This will turn on BT and connect */
BluetoothSocket clientSock =
ObexTest.connectClientSocket(BluetoothSocket.TYPE_L2CAP, true, mContext);
BluetoothObexTransport clientTransport = new BluetoothObexTransport(clientSock);
TestSequencer sequencer = new TestSequencer(clientTransport, null, this);
builder.build(sequencer);
//Debug.startMethodTracing("ObexTrace");
assertTrue(sequencer.run(mContext));
//Debug.stopMethodTracing();
clientSock.close();
} catch (IOException e) {
Log.e(TAG, "IOException", e);
}
if(DELAY_PASS_30_SEC) {
Log.i(TAG, "\n\n\nTest done - please fetch logs within 30 seconds...\n\n\n");
try {
Thread.sleep(30000);
} catch (InterruptedException e) {}
}
}
protected void addConnectStep(TestSequencer sequencer) {
SeqStep step;
// MAP CONNECT Step
step = sequencer.addStep(OPTYPE.CONNECT, null);
HeaderSet hs = new HeaderSet();
hs.setHeader(HeaderSet.TARGET, MAS_TARGET);
step.mReqHeaders = hs;
step.mValidator = new MapConnectValidator();
//step.mServerPreAction = new MapAddSmsMessages(); // could take in parameters
}
protected void addDisconnectStep(TestSequencer sequencer) {
sequencer.addStep(OPTYPE.DISCONNECT, ObexTest.getResponsecodevalidator());
}
/* Functions to validate results */
private class MapConnectValidator implements ISeqStepValidator {
@Override
public boolean validate(SeqStep step, HeaderSet response, Operation notUsed)
throws IOException {
Assert.assertNotNull(response);
byte[] who = (byte[])response.getHeader(HeaderSet.WHO);
Assert.assertNotNull(who);
Assert.assertTrue(Arrays.equals(who, MAS_TARGET));
Assert.assertNotNull(response.getHeader(HeaderSet.CONNECTION_ID));
return true;
}
}
/**
* This is the function creating the Obex Server to be used in this class.
* Here we use a mocked version of the MapObexServer class
*/
@Override
public ServerRequestHandler getObexServer(ArrayList<SeqStep> sequence,
CountDownLatch stopLatch) {
try {
return new MapObexTestServer(mContext, sequence, stopLatch);
} catch (RemoteException e) {
Log.e(TAG, "exception", e);
fail("Unable to create MapObexTestServer");
}
return null;
}
}