/**
* BlueCove - Java library for Bluetooth
* Copyright (C) 2007-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 com.intel.bluetooth;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Enumeration;
import javax.bluetooth.DataElement;
import javax.bluetooth.UUID;
import javax.bluetooth.ServiceRecord;
import junit.framework.TestCase;
/**
*
*/
public class SDPStreamTest extends TestCase {
public static final String stringUTFData = "\u0413\u043E\u043B\u0443\u0431\u043E\u0439\u0417\u0443\u0431";
protected void setUp() throws Exception {
super.setUp();
// System.getProperties().put("bluecove.debug", "true");
}
public static void assertEquals(String message, DataElement de1, DataElement de2) {
if ((de1 == null) || (de2 == null)) {
fail(message + "NULL elements");
}
assertEquals(message + "Type", de1.getDataType(), de2.getDataType());
switch (de1.getDataType()) {
case DataElement.U_INT_1:
case DataElement.U_INT_2:
case DataElement.U_INT_4:
case DataElement.INT_1:
case DataElement.INT_2:
case DataElement.INT_4:
case DataElement.INT_8:
assertEquals(message + "long", de1.getLong(), de2.getLong());
return;
case DataElement.URL:
case DataElement.STRING:
case DataElement.UUID:
assertEquals(message + "value", de1.getValue(), de2.getValue());
return;
case DataElement.INT_16:
case DataElement.U_INT_8:
case DataElement.U_INT_16:
byte[] byteAray1 = (byte[]) de1.getValue();
byte[] byteAray2 = (byte[]) de2.getValue();
assertEquals(message + "length", byteAray1.length, byteAray2.length);
for (int k = 0; k < byteAray1.length; k++) {
assertEquals(message + "byteAray[" + k + "]", byteAray1[k], byteAray2[k]);
}
return;
case DataElement.NULL:
return;
case DataElement.BOOL:
assertEquals(message + "boolean", de1.getBoolean(), de2.getBoolean());
return;
case DataElement.DATSEQ:
case DataElement.DATALT:
int i = 0;
Enumeration en1 = (Enumeration) de1.getValue();
Enumeration en2 = (Enumeration) de2.getValue();
for (; en1.hasMoreElements() && en2.hasMoreElements();) {
DataElement d1 = (DataElement) en1.nextElement();
DataElement d2 = (DataElement) en2.nextElement();
assertEquals(message + "DataElement[" + i + "]", d1, d2);
i++;
}
if (en1.hasMoreElements() || en2.hasMoreElements()) {
fail(message + "unknown hasMoreElements");
}
return;
default:
fail(message + "unknown type");
}
}
public static void assertEquals(String message, ServiceRecord sr1, ServiceRecord sr2) {
int[] ids1 = sr1.getAttributeIDs();
int[] ids2 = sr2.getAttributeIDs();
if ((ids1 == null) || (ids2 == null)) {
return;
}
assertNotNull(message + "sr1.getAttributeIDs", ids1);
assertNotNull(message + "sr2.getAttributeIDs", ids2);
assertEquals(message + "AttributeIDs length", ids1.length, ids2.length);
for (int i = 0; i < ids1.length; i++) {
assertEquals(message + " attr " + ids1[i], sr1.getAttributeValue(ids1[i]), sr2.getAttributeValue(ids1[i]));
}
}
private DataElement doubleCovert(DataElement element) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
(new SDPOutputStream(out)).writeElement(element);
byte blob[] = out.toByteArray();
return (new SDPInputStream(new ByteArrayInputStream(blob))).readElement();
}
private void validateConversion(DataElement element) throws IOException {
DataElement elementConverted = doubleCovert(element);
boolean passed = false;
try {
assertEquals("", element, elementConverted);
passed = true;
} finally {
if (!passed) {
System.out.println("in " + ((Object) element).toString());
System.out.println("out " + ((Object) element).toString());
}
}
}
public void testInt() throws IOException {
validateConversion(new DataElement(DataElement.U_INT_1, 1));
validateConversion(new DataElement(DataElement.U_INT_2, 60));
validateConversion(new DataElement(DataElement.U_INT_4, 77839));
validateConversion(new DataElement(DataElement.INT_1, -7));
validateConversion(new DataElement(DataElement.INT_2, -5));
validateConversion(new DataElement(DataElement.INT_4, -25678));
validateConversion(new DataElement(DataElement.INT_8, 998652497));
validateConversion(new DataElement(DataElement.U_INT_1, 0));
validateConversion(new DataElement(DataElement.U_INT_1, 0xBC));
validateConversion(new DataElement(DataElement.U_INT_2, 0));
validateConversion(new DataElement(DataElement.U_INT_2, 0xABCD));
validateConversion(new DataElement(DataElement.U_INT_4, 0));
validateConversion(new DataElement(DataElement.U_INT_4, 0xABCDEF40l));
validateConversion(new DataElement(DataElement.INT_1, 0));
validateConversion(new DataElement(DataElement.INT_1, 0x4C));
validateConversion(new DataElement(DataElement.INT_1, -0x1E));
validateConversion(new DataElement(DataElement.INT_2, 0));
validateConversion(new DataElement(DataElement.INT_2, 0x5BCD));
validateConversion(new DataElement(DataElement.INT_2, -0x7EFD));
validateConversion(new DataElement(DataElement.INT_4, 0));
validateConversion(new DataElement(DataElement.INT_4, 0x1BCDEF35l));
validateConversion(new DataElement(DataElement.INT_4, -0x2BC7EF35l));
validateConversion(new DataElement(DataElement.INT_8, 0));
validateConversion(new DataElement(DataElement.INT_8, 0x3eC6EF355892EA8Cl));
validateConversion(new DataElement(DataElement.INT_8, -0x7F893012AB39FB72l));
validateConversion(new DataElement(DataElement.U_INT_8, new byte[] { 1, -2, 3, 4, -5, 6, 7, -8 }));
validateConversion(new DataElement(DataElement.INT_16, new byte[] { 11, -22, 33, 44, -5, 6, 77, 88, 9, -10, 11,
12, -13, 14, 15, 16 }));
validateConversion(new DataElement(DataElement.U_INT_16, new byte[] { 21, -32, 43, 54, -65, 76, 87, 98, 11,
-110, 111, 112, -113, 114, 115, 16 }));
}
public void testUUID() throws IOException {
validateConversion(new DataElement(DataElement.UUID, new UUID("0100", true)));
validateConversion(new DataElement(DataElement.UUID, new UUID("B10C0BE1111111111111111111110001", false)));
// This is the same UUIDs
validateConversion(new DataElement(DataElement.UUID, new UUID("0000110500001000800000805f9b34fb", false)));
validateConversion(new DataElement(DataElement.UUID, new UUID(0x1105)));
// UUID 32-bit
validateConversion(new DataElement(DataElement.UUID, new UUID(0x21301107)));
}
public static String getLongString(int lenght) {
StringBuffer b = new StringBuffer();
b.append("b");
for (int i = 0; i < lenght - 2; i++) {
b.append("Z");
}
b.append("e");
return b.toString();
}
public void testString() throws IOException {
validateConversion(new DataElement(DataElement.STRING, ""));
validateConversion(new DataElement(DataElement.STRING, "12345"));
validateConversion(new DataElement(DataElement.STRING, stringUTFData));
validateConversion(new DataElement(DataElement.STRING, getLongString(0x100 + 2)));
}
public void testDATSEQ() throws IOException {
DataElement seq1 = new DataElement(DataElement.DATSEQ);
seq1.addElement(new DataElement(DataElement.STRING, "BlueCove-seq1"));
seq1.addElement(new DataElement(DataElement.U_INT_1, 0x12));
seq1.addElement(new DataElement(DataElement.URL, "http://blueCove/"));
seq1.addElement(new DataElement(DataElement.STRING, stringUTFData));
seq1.addElement(new DataElement(DataElement.UUID, new UUID("B10C0BE1111111111111111111110001", false)));
DataElement seq2 = new DataElement(DataElement.DATSEQ);
seq2.addElement(new DataElement(DataElement.U_INT_8, new byte[] { 1, -2, 3, 4, -5, 6, 7, -8 }));
seq2.addElement(new DataElement(DataElement.STRING, getLongString(0x100 + 2)));
seq2.addElement(new DataElement(DataElement.U_INT_2, 0x14));
DataElement seq3 = new DataElement(DataElement.DATSEQ);
seq3.addElement(new DataElement(DataElement.U_INT_4, 0x15));
seq3.addElement(new DataElement(DataElement.STRING, stringUTFData));
seq3.addElement(new DataElement(DataElement.UUID, new UUID(0x1105)));
seq3.addElement(new DataElement(DataElement.INT_8, 0x16));
seq1.addElement(seq2);
seq1.addElement(seq3);
seq1.addElement(new DataElement(DataElement.INT_4, 0x1BCDEF35l));
validateConversion(seq1);
}
public void testDATSEQ16() throws IOException {
DataElement seq = new DataElement(DataElement.DATSEQ);
// INT_8 = 9 bytes;
int nElements = (0xFF / 9) + 1;
for (int i = 0; i < nElements; i++) {
seq.addElement(new DataElement(DataElement.INT_8, i));
}
int l = SDPOutputStream.getLength(seq);
assertTrue("DATSEQ16 len(" + l + ")>0xFF", l > 0xFF);
assertTrue("DATSEQ16 len(" + l + ")<0xFFFF", l < 0xFFFF);
validateConversion(seq);
}
public void testDATSEQ32() throws IOException {
DataElement seq = new DataElement(DataElement.DATSEQ);
// INT_8 = 9 bytes;
int nElements = (0xFFFF / 9) + 1;
for (int i = 0; i < nElements; i++) {
seq.addElement(new DataElement(DataElement.INT_8, i));
}
int l = SDPOutputStream.getLength(seq);
assertTrue("DATSEQ32 len(" + l + ")>0xFFFF", l > 0xFFFF);
validateConversion(seq);
}
public void testOtherAttributes() throws IOException {
validateConversion(new DataElement(true));
validateConversion(new DataElement(false));
validateConversion(new DataElement(DataElement.NULL));
}
public void validateServiceRecordConvert(String message, ServiceRecordImpl serviceRecord) throws IOException {
byte[] data = serviceRecord.toByteArray();
ServiceRecordImpl serviceRecord2 = new ServiceRecordImpl(null, null, 0);
serviceRecord2.loadByteArray(data);
assertEquals(message, serviceRecord, serviceRecord2);
}
public void testServiceRecordConvertion() throws IOException {
ServiceRecordImpl serviceRecord = new ServiceRecordImpl(null, null, 0);
serviceRecord.populateL2CAPAttributes(1, 2, new UUID(3), "BBBB");
validateServiceRecordConvert("L2CAP", serviceRecord);
ServiceRecordImpl serviceRecord2 = new ServiceRecordImpl(null, null, 0);
serviceRecord2.populateRFCOMMAttributes(1, 2, new UUID(3), "BBBB", true);
validateServiceRecordConvert("RFCOMM", serviceRecord2);
}
}