/**
* BlueCove - Java library for Bluetooth
* Copyright (C) 2008-2009 Vlad Skarzhevskyy
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
* @author vlads
* @version $Id$
*/
package net.sf.bluecove.obex;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.microedition.io.Connector;
import javax.obex.ClientSession;
import javax.obex.HeaderSet;
import javax.obex.Operation;
import javax.obex.ResponseCodes;
import javax.obex.ServerRequestHandler;
import com.intel.bluetooth.DebugLog;
import com.intel.bluetooth.obex.BlueCoveInternals;
import com.intel.bluetooth.obex.BlueCoveOBEX;
/**
*
*/
public class OBEXPutConditionsTest extends OBEXBaseEmulatorTestCase {
private int serverDataLength;
private byte[] serverData;
private static long LENGTH_NO_DATA = 0xffffffffl;
private volatile int serverResponseCode = ResponseCodes.OBEX_HTTP_OK;
@Override
protected void setUp() throws Exception {
super.setUp();
serverDataLength = -1;
serverData = null;
serverResponseCode = 0;
}
private class RequestHandler extends ServerRequestHandler {
@Override
public int onPut(Operation op) {
try {
serverRequestHandlerInvocations++;
DebugLog.debug("==TEST== serverRequestHandlerInvocations", serverRequestHandlerInvocations);
if (serverRequestHandlerInvocations > 1) {
return ResponseCodes.OBEX_HTTP_BAD_REQUEST;
}
serverHeaders = op.getReceivedHeaders();
Long dataLength = (Long) serverHeaders.getHeader(HeaderSet.LENGTH);
if (dataLength == null) {
serverResponseCode = ResponseCodes.OBEX_HTTP_LENGTH_REQUIRED;
return serverResponseCode;
}
long length = dataLength.longValue();
int len = (int) length;
if (length != LENGTH_NO_DATA) {
InputStream is = op.openInputStream();
serverData = new byte[len];
int got = 0;
// read fully
while (got < len) {
int rc = is.read(serverData, got, len - got);
if (rc < 0) {
break;
}
got += rc;
}
is.close();
serverDataLength = got;
}
op.close();
serverResponseCode = ResponseCodes.OBEX_HTTP_OK;
return serverResponseCode;
} catch (IOException e) {
e.printStackTrace();
return ResponseCodes.OBEX_HTTP_UNAVAILABLE;
}
}
}
@Override
protected ServerRequestHandler createRequestHandler() {
return new RequestHandler();
}
private void runPUTOperation(boolean flush, long length, byte[] data1, byte[] data2, int expectedPackets)
throws IOException {
ClientSession clientSession = (ClientSession) Connector.open(selectService(serverUUID));
HeaderSet hsConnectReply = clientSession.connect(null);
assertEquals("connect", ResponseCodes.OBEX_HTTP_OK, hsConnectReply.getResponseCode());
int writePacketsConnect = BlueCoveInternals.getPacketsCountWrite(clientSession);
HeaderSet hsOperation = clientSession.createHeaderSet();
hsOperation.setHeader(HeaderSet.LENGTH, new Long(length));
DebugLog.debug("==TEST== client start put");
// Create PUT Operation
Operation putOperation = clientSession.put(hsOperation);
DebugLog.debug("==TEST== client openOutputStream");
OutputStream os = putOperation.openOutputStream();
os.write(data1);
if (flush) {
DebugLog.debug("==TEST== client flush 1");
os.flush();
}
if (data2 != null) {
os.write(data2);
if (flush) {
DebugLog.debug("test client flush 2");
os.flush();
}
}
DebugLog.debug("==TEST== client OutputStream close");
os.close();
int responseCode = putOperation.getResponseCode();
DebugLog.debug0x("==TEST== Client ResponseCode " + BlueCoveOBEX.obexResponseCodes(responseCode) + " = ",
responseCode);
DebugLog.debug("==TEST== client Operation close");
putOperation.close();
DebugLog.debug("==TEST== client PUT packets", BlueCoveInternals.getPacketsCountWrite(clientSession)
- writePacketsConnect);
DebugLog.debug("==TEST== client Session disconnect");
clientSession.disconnect(null);
clientSession.close();
assertEquals("invocations", 1, serverRequestHandlerInvocations);
assertEquals("LENGTH", new Long(length), serverHeaders.getHeader(HeaderSet.LENGTH));
assertEquals("data.length", data1.length, serverDataLength);
assertEquals("ResponseCodes." + BlueCoveOBEX.obexResponseCodes(serverResponseCode), serverResponseCode,
responseCode);
assertEquals("c.writePackets", expectedPackets, BlueCoveInternals.getPacketsCountWrite(clientSession));
assertEquals("c.readPackets", expectedPackets, BlueCoveInternals.getPacketsCountRead(clientSession));
assertEquals("s.writePackets", expectedPackets, BlueCoveInternals
.getPacketsCountWrite(getServerAcceptedConnection()));
assertEquals("s.readPackets", expectedPackets, BlueCoveInternals
.getPacketsCountRead(getServerAcceptedConnection()));
assertServerErrors();
}
/**
* Verify that server can read data without getting to the exact end of file in InputStream
*/
public void testPUTOperationComplete() throws IOException {
byte data[] = simpleData;
int expectedPackets = 1 + 2 + 1;
runPUTOperation(false, data.length, data, null, expectedPackets);
assertEquals("data", data, serverData);
}
public void testPUTOperationCompleteBigData() throws IOException {
int mtu = 0x400; // OBEX_DEFAULT_MTU
// Send big Data to server
int length = 0x4001;
byte data[] = makeTestData(length);
int dataNeedPackets = length / mtu;
if ((length % mtu) > 0) {
dataNeedPackets++;
}
int expectedPackets = 1 + 1 + dataNeedPackets + 1;
runPUTOperation(false, data.length, data, null, expectedPackets);
assertEquals("data", data, serverData);
}
/**
* Verify that call to flush do not cause double invocation for onPut
*/
public void testPUTOperationCompleteFlush() throws IOException {
byte data[] = simpleData;
int expectedPackets = 1 + 2 + 1 + 1;
runPUTOperation(true, data.length, data, null, expectedPackets);
assertEquals("data", data, serverData);
}
public void testPUTOperationCompleteFlushBigData() throws IOException {
int mtu = 0x400; // OBEX_DEFAULT_MTU
// Send big Data to server
int length = 0x4001;
byte data[] = makeTestData(length);
int dataNeedPackets = length / mtu;
if ((length % mtu) > 0) {
dataNeedPackets++;
}
int expectedPackets = 1 + 1 + dataNeedPackets + 1 + 1;
runPUTOperation(true, data.length, data, null, expectedPackets);
assertEquals("data", data, serverData);
}
public void testPUTOperationSendMore() throws IOException {
byte data[] = simpleData;
int expectedPackets = 1 + 2 + 1;
runPUTOperation(false, data.length, data, "More".getBytes("iso-8859-1"), expectedPackets);
assertEquals("data", data, serverData);
}
public void testPUTOperationSendMoreBigData() throws IOException {
int mtu = 0x400; // OBEX_DEFAULT_MTU
// Send big Data to server
int length = 0x4001;
byte data[] = makeTestData(length);
byte data2[] = makeTestData(mtu * 3 + 10);
length += data2.length;
int dataNeedPackets = length / mtu;
if ((length % mtu) > 0) {
dataNeedPackets++;
}
int expectedPackets = 1 + 1 + dataNeedPackets + 1;
runPUTOperation(false, data.length, data, data2, expectedPackets);
assertEquals("data", data, serverData);
}
public void testPUTOperationSendLess() throws IOException {
byte data[] = simpleData;
int less = 4;
int expectedPackets = 1 + 2 + 1;
runPUTOperation(false, data.length + less, data, null, expectedPackets);
assertEquals("data", data.length, data, serverData);
}
public void testPUTOperationSendLessBigData() throws IOException {
int mtu = 0x400; // OBEX_DEFAULT_MTU
// Send big Data to server
byte data[] = makeTestData(0x4001);
int less = mtu * 3 + 11;
int length = data.length;
int dataNeedPackets = length / mtu;
if ((length % mtu) > 0) {
dataNeedPackets++;
}
int expectedPackets = 1 + 1 + dataNeedPackets + 1;
runPUTOperation(false, length + less, data, null, expectedPackets);
assertEquals("data", data.length, data, serverData);
}
/**
* No data in Operation OutputStream
*/
public void testPUTOperationNoData() throws IOException {
ClientSession clientSession = (ClientSession) Connector.open(selectService(serverUUID));
HeaderSet hsConnectReply = clientSession.connect(null);
assertEquals("connect", ResponseCodes.OBEX_HTTP_OK, hsConnectReply.getResponseCode());
int writePacketsConnect = BlueCoveInternals.getPacketsCountWrite(clientSession);
HeaderSet hs = clientSession.createHeaderSet();
String name = "Hello.txt";
hs.setHeader(HeaderSet.NAME, name);
hs.setHeader(HeaderSet.LENGTH, new Long(LENGTH_NO_DATA));
// Create PUT Operation
Operation putOperation = clientSession.put(hs);
OutputStream os = putOperation.openOutputStream();
os.close();
int responseCode = putOperation.getResponseCode();
DebugLog.debug0x("==TEST== Client ResponseCode " + BlueCoveOBEX.obexResponseCodes(responseCode) + " = ",
responseCode);
putOperation.close();
DebugLog.debug("PUT packets", BlueCoveInternals.getPacketsCountWrite(clientSession) - writePacketsConnect);
clientSession.disconnect(null);
clientSession.close();
assertEquals("NAME", name, serverHeaders.getHeader(HeaderSet.NAME));
assertNull("data", serverData);
assertEquals("invocations", 1, serverRequestHandlerInvocations);
assertEquals("ResponseCodes." + BlueCoveOBEX.obexResponseCodes(serverResponseCode), serverResponseCode,
responseCode);
int expectedPackets = 1 + 2 + 1;
assertEquals("c.writePackets", expectedPackets, BlueCoveInternals.getPacketsCountWrite(clientSession));
assertEquals("c.readPackets", expectedPackets, BlueCoveInternals.getPacketsCountRead(clientSession));
assertEquals("s.writePackets", expectedPackets, BlueCoveInternals
.getPacketsCountWrite(getServerAcceptedConnection()));
assertEquals("s.readPackets", expectedPackets, BlueCoveInternals
.getPacketsCountRead(getServerAcceptedConnection()));
assertServerErrors();
}
}