1package com.android.bluetooth.tests; 2 3import java.io.IOException; 4import java.util.concurrent.CountDownLatch; 5 6import javax.obex.ClientSession; 7import javax.obex.HeaderSet; 8import javax.obex.Operation; 9import javax.obex.ResponseCodes; 10import javax.obex.ServerSession; 11 12import com.android.bluetooth.BluetoothObexTransport; 13import com.android.bluetooth.sdp.SdpManager; 14 15import android.annotation.TargetApi; 16import android.bluetooth.BluetoothAdapter; 17import android.bluetooth.BluetoothDevice; 18import android.bluetooth.BluetoothServerSocket; 19import android.bluetooth.BluetoothSocket; 20import android.bluetooth.BluetoothUuid; 21import android.graphics.Paint.Join; 22import android.os.Build; 23import android.test.AndroidTestCase; 24import android.util.Log; 25 26import junit.framework.Assert; 27 28@TargetApi(Build.VERSION_CODES.KITKAT) 29public class SdpManagerTest extends AndroidTestCase { 30 31 protected static String TAG = "SdpManagerTest"; 32 protected static final boolean D = true; 33 34 public static final int SDP_RECORD_COUNT = 12; /* Maximum number of records to create */ 35 public static final int SDP_ITERATIONS = 2000; 36 37 public static final String SDP_SERVER_NAME = "SDP test server"; 38 public static final String SDP_CLIENT_NAME = "SDP test client"; 39 40 public static final long SDP_FEATURES = 0x87654321L; /* 32 bit */ 41 public static final int SDP_MSG_TYPES = 0xf1; /* 8 bit */ 42 public static final int SDP_MAS_ID = 0xCA; /* 8 bit */ 43 public static final int SDP_VERSION = 0xF0C0; /* 16 bit */ 44 public static final int SDP_REPOS = 0xCf; /* 8 bit */ 45 46 SdpManager mManager = null; 47 48 public void testSdpRemove() { 49 BluetoothAdapter bt = BluetoothAdapter.getDefaultAdapter(); 50 if(bt == null) { 51 Log.e(TAG,"No Bluetooth Device!"); 52 assertTrue(false); 53 } 54 BluetoothTestUtils.enableBt(bt); 55 mManager = SdpManager.getDefaultManager(); 56 addRemoveRecords(SDP_RECORD_COUNT); 57 } 58 59 public void testSdpAdd() { 60 BluetoothAdapter bt = BluetoothAdapter.getDefaultAdapter(); 61 if(bt == null) { 62 Log.e(TAG,"No Bluetooth Device!"); 63 assertTrue(false); 64 } 65 BluetoothTestUtils.enableBt(bt); 66 mManager = SdpManager.getDefaultManager(); 67 68 int handles[] = new int[SDP_RECORD_COUNT]; 69 addRecords(handles, 1); 70 71 try { 72 Log.i(TAG, "\n\n\nRecords added - waiting 5 minutes...\n\n\n"); 73 Thread.sleep(300000); 74 } catch (InterruptedException e) { 75 Log.e(TAG, "Interrupted", e); 76 } 77 Log.i(TAG, "All done - over and out!;-)"); 78 } 79 80 81 private void addRecords(int handles[], int iteration) { 82 /* Create the records */ 83 int record_id = -1; /* first index is 0 */ 84 int count = handles.length-1; // Break condition 85 for(int c = 0; ; c++) { 86 Log.i(TAG, "Create c=" + c); 87 handles[++record_id] = mManager.createMapMasRecord(SDP_SERVER_NAME, 88 SDP_MAS_ID, record_id, record_id+iteration, SDP_VERSION, 89 SDP_MSG_TYPES, (int)SDP_FEATURES); 90 Log.i(TAG, " Added record_handle=" + handles[record_id]); 91 assertTrue(handles[record_id]>=0); 92 if(record_id == count) break; 93 94 handles[++record_id] = mManager.createMapMnsRecord(SDP_SERVER_NAME, 95 record_id, record_id+iteration, SDP_VERSION, 96 (int)SDP_FEATURES); 97 Log.i(TAG, " Added record_handle=" + handles[record_id]); 98 assertTrue(handles[record_id]>=0); 99 if(record_id == count) break; 100 101 handles[++record_id] = mManager.createOppOpsRecord(SDP_SERVER_NAME, 102 record_id, record_id+iteration, SDP_VERSION, SdpManager.OPP_FORMAT_ALL); 103 Log.i(TAG, " Added record_handle=" + handles[record_id]); 104 assertTrue(handles[record_id]>=0); 105 if(record_id == count) break; 106 107 handles[++record_id] = mManager.createPbapPseRecord(SDP_SERVER_NAME, 108 record_id, record_id+iteration, SDP_VERSION, SDP_REPOS, 109 (int)SDP_FEATURES); 110 Log.i(TAG, " Added record_handle=" + handles[record_id]); 111 assertTrue(handles[record_id]>=0); 112 if(record_id == count) break; 113 114 handles[++record_id] = mManager.createSapsRecord(SDP_SERVER_NAME, 115 record_id, SDP_VERSION); 116 Log.i(TAG, " Added record_handle=" + handles[record_id]); 117 assertTrue(handles[record_id]>=0); 118 if (record_id == count) break; 119 } 120 } 121 122 void removeRecords(int handles[], int record_count) { 123 int record_id; 124 /* Remove the records */ 125 for(record_id = 0; record_id < record_count; record_id++) { 126 Log.i(TAG, "remove id=" + record_id); 127 assertTrue(mManager.removeSdpRecord(handles[record_id])); 128 } 129 } 130 131 private void addRemoveRecords(int count) { 132 int record_count = count; 133 int handles[] = new int[record_count]; 134 int iteration; 135 for(iteration = 0; iteration < SDP_ITERATIONS; iteration++) { 136 137 addRecords(handles, iteration); 138 139 try { 140 Thread.sleep(500); 141 } catch (InterruptedException e) { 142 Log.e(TAG, "Interrupted", e); 143 } 144 145 removeRecords(handles, record_count); 146 } 147 } 148 149 /** 150 * Client side of SdpSearch test 151 * This test will: 152 * 1) Create a connection to a test server 153 * 2) Create a number of SDP records 154 * 3) Request the test server to read the records 155 * 4) Remove the records 156 * 5) Iterate over 2) to 4) SDP_ITERATIONS number of times 157 */ 158 public void testSdpSearchClient() { 159 int count = SDP_RECORD_COUNT; 160 int record_count = count; 161 int handles[] = new int[record_count]; 162 int iteration; 163 final BluetoothSocket clientSock; 164 final ClientSession mClientSession; 165 final String[] uuids = {BluetoothUuid.MAS.toString(), 166 BluetoothUuid.MNS.toString(), 167 BluetoothUuid.PBAP_PSE.toString(), 168 BluetoothUuid.ObexObjectPush.toString(), 169 BluetoothUuid.SAP.toString()}; 170 final String uuids_str; 171 final StringBuilder sb = new StringBuilder(uuids.length*2-1); 172 for(String str : uuids) { 173 sb.append(str).append(";"); 174 } 175 uuids_str = sb.toString(); 176 177 try { 178 /* This will turn on BT and connect */ 179 clientSock = ObexTest.connectClientSocket(BluetoothSocket.TYPE_L2CAP, true, mContext); 180 mManager = SdpManager.getDefaultManager(); 181 BluetoothObexTransport clientTransport = new BluetoothObexTransport(clientSock); 182 mClientSession = new ClientSession(clientTransport); 183 { // Connect 184 HeaderSet reqHeaders = new HeaderSet(); 185 reqHeaders.setHeader(TestSequencer.STEP_INDEX_HEADER, (long)0); 186 HeaderSet response = mClientSession.connect(reqHeaders); 187 assertEquals(response.responseCode, ResponseCodes.OBEX_HTTP_OK); 188 } 189 190 for(iteration = 0; iteration < SDP_ITERATIONS; iteration++) { 191 // Add the records 192 addRecords(handles, iteration); 193 194 { // get operation to trigger SDP search on peer device 195 HeaderSet reqHeaders = new HeaderSet(); 196 reqHeaders.setHeader(TestSequencer.STEP_INDEX_HEADER, (long)iteration); 197 reqHeaders.setHeader(HeaderSet.COUNT, (long)count); 198 reqHeaders.setHeader(HeaderSet.NAME, uuids_str); 199 Operation op = mClientSession.get(reqHeaders); 200 op.noBodyHeader(); 201 int response = op.getResponseCode(); 202 op.close(); 203 assertEquals(response, ResponseCodes.OBEX_HTTP_OK); 204 } 205 206 // Cleanup 207 removeRecords(handles, record_count); 208 } 209 { // disconnect to end test 210 HeaderSet reqHeaders = new HeaderSet(); 211 reqHeaders.setHeader(TestSequencer.STEP_INDEX_HEADER, 0L); // signals end of test 212 HeaderSet response = mClientSession.disconnect(reqHeaders); 213 assertEquals(response.responseCode, ResponseCodes.OBEX_HTTP_OK); 214 } 215 } catch (IOException e) { 216 Log.e(TAG,"IOException in testSdpSearch",e); 217 } 218 219 } 220 221 /** 222 * Server side of SdpSearch test 223 * This test will start a 224 * 1) Create a connection to a test server 225 * 2) Create a number of SDP records 226 * 3) Request the test server to read the records 227 * 4) Remove the records 228 * 5) Iterate over 2) to 4) SDP_ITERATIONS number of times 229 */ 230 public void testSdpSearchServer() { 231 mManager = SdpManager.getDefaultManager(); 232 try { 233 CountDownLatch stopLatch = new CountDownLatch(1); 234 BluetoothDevice clientDevice; 235 /* This will turn on BT and create a server socket on which accept can be called. */ 236 BluetoothServerSocket serverSocket=ObexTest.createServerSocket(BluetoothSocket.TYPE_L2CAP, true); 237 mManager = SdpManager.getDefaultManager(); 238 239 Log.i(TAG, "Waiting for client to connect..."); 240 BluetoothSocket socket = serverSocket.accept(); 241 Log.i(TAG, "Client connected..."); 242 243 BluetoothObexTransport serverTransport = new BluetoothObexTransport(socket); 244 clientDevice = socket.getRemoteDevice(); 245 ServerSession serverSession = new ServerSession(serverTransport, 246 new SdpManagerTestServer(stopLatch, mContext, clientDevice), null); 247 248 boolean interrupted = false; 249 do { 250 try { 251 interrupted = false; 252 Log.i(TAG,"Waiting for stopLatch signal..."); 253 stopLatch.await(); 254 } catch (InterruptedException e) { 255 Log.w(TAG,e); 256 interrupted = true; 257 } 258 } while (interrupted == true); 259 Log.i(TAG,"stopLatch signal received closing down..."); 260 /* Give a little time to transfer the disconnect response before closing the socket */ 261 try { 262 Thread.sleep(1000); 263 } catch (InterruptedException e) {} 264 265 // Cleanup 266 serverSession.close(); 267 socket.close(); 268 serverSocket.close(); 269 } catch (IOException e) { 270 Log.e(TAG, "IOException", e); 271 } 272 Log.i(TAG, "\n\n\nTest done - please fetch logs within 30 seconds...\n\n\n"); 273 try { 274 Thread.sleep(30000); 275 } catch (InterruptedException e) {} 276 Log.i(TAG, "Test done."); 277} 278 279 280/* 281 * Tests we need: 282 * - Single threaded test: 283 * * Add a large number of records and remove them again. 284 * - Multi-threaded rests: 285 * * Let two or more threads perform the test above, each tasking a n-threads fraction of the RECORD_COUNT 286 * 287 * - Client/server 288 * * Create a control connection - it might be easiest to use OBEX. 289 * 1) Add a number of records 290 * 2) Trigger read of the records 291 * 3) Remove the records 292 * 4) Validate they are gone (if they are not cached) 293 * 5) Multi thread the test on both sides? 294 * */ 295 296} 297