| package com.android.bluetooth.tests; |
| |
| import android.net.LocalSocket; |
| import android.net.LocalSocketAddress; |
| import android.test.AndroidTestCase; |
| import android.util.Log; |
| |
| import org.android.btsap.SapApi; |
| import org.android.btsap.SapApi.MsgHeader; |
| import org.android.btsap.SapApi.RIL_SIM_SAP_CONNECT_REQ; |
| |
| import com.google.protobuf.micro.ByteStringMicro; |
| import com.google.protobuf.micro.CodedOutputStreamMicro; |
| import com.google.protobuf.micro.CodedInputStreamMicro; |
| |
| import java.io.IOException; |
| import java.io.OutputStream; |
| import java.io.InputStream; |
| import java.util.Arrays; |
| |
| public class SapSocketTest extends AndroidTestCase { |
| |
| protected static String TAG = "SapSocketTest"; |
| protected static final boolean D = true; |
| |
| private static final String SOCKET_NAME_RIL_BT = "sap_uim_socket1"; |
| |
| public SapSocketTest() { |
| super(); |
| } |
| |
| private void writeLegacyLength(int length, OutputStream rawOut) throws IOException { |
| byte[] dataLength = new byte[4]; |
| dataLength[0] = dataLength[1] = 0; |
| dataLength[2] = (byte)((length >> 8) & 0xff); |
| dataLength[3] = (byte)((length) & 0xff); |
| rawOut.write(dataLength); |
| } |
| |
| private void dumpMsgHeader(MsgHeader msg){ |
| Log.d(TAG,"MsgHeader: ID = " + msg.getId()); |
| Log.d(TAG," Type= " + msg.getType()); |
| Log.d(TAG," Token= " + msg.getToken()); |
| Log.d(TAG," Error= " + msg.getError()); |
| Log.d(TAG," Length=" + msg.getSerializedSize()); |
| if(msg.hasPayload()){ |
| Log.d(TAG,"Payload: Length=" + msg.getPayload().size()); |
| Log.d(TAG," Data= " + Arrays.toString(msg.getPayload().toByteArray())); |
| } |
| |
| } |
| private void readLegacyLength(InputStream rawIn) throws IOException{ |
| byte[] buffer = new byte[4]; |
| int countRead; |
| int offset; |
| int remaining; |
| int messageLength; |
| |
| // Read in the length of the message |
| offset = 0; |
| remaining = 4; |
| do { |
| countRead = rawIn.read(buffer, offset, remaining); |
| |
| if (countRead < 0 ) { |
| Log.e(TAG, "Hit EOS reading message length"); |
| return; |
| } |
| |
| offset += countRead; |
| remaining -= countRead; |
| } while (remaining > 0); |
| |
| messageLength = ((buffer[0] & 0xff) << 24) |
| | ((buffer[1] & 0xff) << 16) |
| | ((buffer[2] & 0xff) << 8) |
| | (buffer[3] & 0xff); |
| |
| Log.d(TAG, "The length is: " + messageLength + " - discarding as we do not need it"); |
| |
| } |
| |
| /** |
| Precondition: |
| Add the sap_uim_socket1 to rild in init.rc: |
| socket sap_uim_socket1 stream 666 root bluetooth |
| |
| Ensure the socket is present in /dev/socket: |
| srw-rw-rw- root bluetooth 1970-04-16 06:27 sap_uim_socket1 |
| |
| Build: |
| mmm packages/apps/Bluetooth/tests |
| |
| rebuild with a make in the root folder to get the |
| android.test.InstrumentationTestRunner class included. |
| |
| Run the test(remove line breaks): |
| adb shell am instrument -w -e class com.android.bluetooth. |
| tests.SapSocketTest#testSapServerConnectSimple com.android. |
| bluetooth.tests/android.test.InstrumentationTestRunner |
| |
| Validate you do not get a permission denied IOException. |
| |
| Validate you do not get an error in the kernel log: |
| type=1400 audit(1404244298.582:25): avc: denied { write } |
| for pid=2421 comm="ationTestRunner" name="sap_uim_socket1" |
| dev="tmpfs" ino=6703 scontext=u:r:bluetooth:s0 |
| tcontext=u:object_r:socket_device:s0 tclass=sock_file |
| */ |
| |
| /** |
| * Precondition: Add the sap_uim_socket1 to rild in init.rc: socket |
| * sap_uim_socket1 stream 666 root bluetooth |
| * |
| * Ensure the socket is present in /dev/socket: srw-rw-rw- root bluetooth |
| * 1970-04-16 06:27 sap_uim_socket1 |
| * |
| * Build: mmm packages/apps/Bluetooth/tests |
| * |
| * rebuild with a make in the root folder to get the |
| * android.test.InstrumentationTestRunner class included. |
| * |
| * Run the test(remove line breaks): adb shell am instrument -w -e class |
| * com.android.bluetooth. tests.SapSocketTest#testSapServerConnectSimple |
| * com.android. bluetooth.tests/android.test.InstrumentationTestRunner |
| * |
| * Validate you do not get a permission denied IOException. |
| * |
| * Validate you do not get an error in the kernel log: type=1400 |
| * audit(1404244298.582:25): avc: denied { write } for pid=2421 |
| * comm="ationTestRunner" name="sap_uim_socket1" dev="tmpfs" ino=6703 |
| * scontext=u:r:bluetooth:s0 tcontext=u:object_r:socket_device:s0 |
| * tclass=sock_file |
| */ |
| public void testSapServerConnectSimple() { |
| LocalSocketAddress address; |
| LocalSocket rilSocket = new LocalSocket(); |
| try { |
| address = new LocalSocketAddress(SOCKET_NAME_RIL_BT, |
| LocalSocketAddress.Namespace.RESERVED); |
| rilSocket.connect(address); |
| CodedInputStreamMicro in = CodedInputStreamMicro.newInstance(rilSocket.getInputStream()); |
| OutputStream rawOut = rilSocket.getOutputStream(); |
| CodedOutputStreamMicro out = CodedOutputStreamMicro.newInstance(rilSocket.getOutputStream()); |
| InputStream rawIn = rilSocket.getInputStream(); |
| int rilSerial = 1; |
| SapApi.MsgHeader msg = new MsgHeader(); |
| /* Common variables for all requests */ |
| msg.setToken(rilSerial); |
| msg.setType(SapApi.REQUEST); |
| msg.setError(SapApi.RIL_E_UNUSED); |
| SapApi.RIL_SIM_SAP_CONNECT_REQ reqMsg = new RIL_SIM_SAP_CONNECT_REQ(); |
| reqMsg.setMaxMessageSize(1234); |
| msg.setId(SapApi.RIL_SIM_SAP_CONNECT); |
| msg.setPayload(ByteStringMicro.copyFrom(reqMsg.toByteArray())); |
| writeLegacyLength(msg.getSerializedSize(), rawOut); |
| msg.writeTo(out); |
| out.flush(); |
| readLegacyLength(rawIn); |
| msg = MsgHeader.parseFrom(in); |
| dumpMsgHeader(msg); |
| assertTrue("Invalid response type", msg.getType()== SapApi.RESPONSE); |
| assertTrue("Invalid response id", msg.getId()== SapApi.RIL_SIM_SAP_CONNECT); |
| } catch (IOException e){ |
| Log.e(TAG, "IOException:", e); |
| assertTrue("Failed to connect to the socket " + SOCKET_NAME_RIL_BT + ":" + e, false); |
| } finally { |
| try { |
| rilSocket.close(); |
| } catch (IOException e2) {} |
| |
| } |
| } |
| } |