1cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bondepackage com.android.bluetooth.sap; 2cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde 3cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bondeimport java.io.IOException; 4cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bondeimport java.io.InputStream; 5cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bondeimport java.io.OutputStream; 6cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde 7cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bondeimport org.android.btsap.SapApi.MsgHeader; 8cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde 9cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bondeimport com.google.protobuf.micro.CodedInputStreamMicro; 10cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bondeimport com.google.protobuf.micro.CodedOutputStreamMicro; 11cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde 12cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bondeimport android.net.LocalSocket; 13cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bondeimport android.net.LocalSocketAddress; 14cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bondeimport android.os.Handler; 15cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bondeimport android.os.Message; 16cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bondeimport android.util.Log; 17cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde 18cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bondepublic class SapRilReceiver implements Runnable { 19cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde 20cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde private static final String TAG = "SapRilReceiver"; 21cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde public static final boolean DEBUG = true; 22cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde public static final boolean VERBOSE = true; 23cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde 24cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde private static final String SOCKET_NAME_RIL_BT = "sap_uim_socket1"; 25cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde // match with constant in ril.cpp - as in RIL.java 26cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde private static final int SOCKET_OPEN_RETRY_MILLIS = 4 * 1000; 27cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde 28cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde LocalSocket mSocket = null; 29cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde CodedOutputStreamMicro mRilBtOutStream = null; 30cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde InputStream mRilBtInStream = null; 31cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde private Handler mSapServerMsgHandler = null; 32bbb071e6d73df46230ec654e3066a46f6e35a88dCasper Bonde private Handler mSapServiceHandler = null; 33cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde 34cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde public static final int RIL_MAX_COMMAND_BYTES = (8 * 1024); 35cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde byte[] buffer = new byte[RIL_MAX_COMMAND_BYTES]; 36cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde 37bbb071e6d73df46230ec654e3066a46f6e35a88dCasper Bonde public SapRilReceiver(Handler SapServerMsgHandler, Handler sapServiceHandler) { 38cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde mSapServerMsgHandler = SapServerMsgHandler; 39bbb071e6d73df46230ec654e3066a46f6e35a88dCasper Bonde mSapServiceHandler = sapServiceHandler; 40cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde } 41cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde 42cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde /** 43cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde * Open the RIL-BT socket in rild. Will continuously try to open the BT socket until 44cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde * success. (Based on the approach used to open the rild socket in telephony) 45cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde * @return The socket handle 46cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde */ 47cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde public static LocalSocket openRilBtSocket() { 48cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde int retryCount = 0; 49cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde LocalSocket rilSocket = null; 50cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde 51cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde for (;;) { 52cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde LocalSocketAddress address; 53cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde 54cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde try { 55cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde rilSocket = new LocalSocket(); 56cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde address = new LocalSocketAddress(SOCKET_NAME_RIL_BT, 57cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde LocalSocketAddress.Namespace.RESERVED); 58cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde rilSocket.connect(address); 59cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde break; // Socket opened 60cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde } catch (IOException ex){ 61cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde try { 62cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde if (rilSocket != null) { 63cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde rilSocket.close(); 64cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde } 65cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde } catch (IOException ex2) { 66cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde //ignore failure to close after failure to connect 67cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde } 68cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde 69cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde // don't print an error message after the the first time 70cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde // or after the 8th time 71cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde if (retryCount == 8) { 72cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde Log.e (TAG, 73cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde "Couldn't find '" + SOCKET_NAME_RIL_BT 74cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde + "' socket after " + retryCount 75cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde + " times, continuing to retry silently"); 76cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde } else if (retryCount > 0 && retryCount < 8) { 77cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde Log.i (TAG, 78cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde "Couldn't find '" + SOCKET_NAME_RIL_BT 79cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde + "' socket; retrying after timeout"); 80bbb071e6d73df46230ec654e3066a46f6e35a88dCasper Bonde if (VERBOSE) Log.w(TAG, ex); 81cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde } 82cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde 83cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde try { 84cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde Thread.sleep(SOCKET_OPEN_RETRY_MILLIS); 85cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde } catch (InterruptedException er) { 86cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde } 87cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde 88cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde retryCount++; 89cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde continue; 90cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde } 91cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde } 92cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde return rilSocket; 93cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde } 94cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde 95cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde 96cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde public CodedOutputStreamMicro getRilBtOutStream() { 97cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde return mRilBtOutStream; 98cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde } 99cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde 100a49b4e45faf378e3848c4f6eb468e0a14565aa6cCasper Bonde /** 101a49b4e45faf378e3848c4f6eb468e0a14565aa6cCasper Bonde * Notify SapServer that this class is ready for shutdown. 102a49b4e45faf378e3848c4f6eb468e0a14565aa6cCasper Bonde */ 103a49b4e45faf378e3848c4f6eb468e0a14565aa6cCasper Bonde private void notifyShutdown() { 104a49b4e45faf378e3848c4f6eb468e0a14565aa6cCasper Bonde if (DEBUG) Log.i(TAG, "notifyShutdown()"); 105a49b4e45faf378e3848c4f6eb468e0a14565aa6cCasper Bonde // If we are already shutdown, don't bother sending a notification. 106a49b4e45faf378e3848c4f6eb468e0a14565aa6cCasper Bonde synchronized (this) { 107a49b4e45faf378e3848c4f6eb468e0a14565aa6cCasper Bonde if (mSocket != null) sendShutdownMessage(); 108a49b4e45faf378e3848c4f6eb468e0a14565aa6cCasper Bonde } 109cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde } 110cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde 111cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde /** 112cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde * This will terminate the SapRilReceiver thread, by closing the RIL-BT in-/output 113cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde * streams. 114cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde */ 115cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde public void shutdown() { 116bbb071e6d73df46230ec654e3066a46f6e35a88dCasper Bonde if (DEBUG) Log.i(TAG, "shutdown()"); 117cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde 118cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde /* On Android you need to close the IOstreams using Socket.shutdown* 119cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde * The IOstream close must not be used, as it some how decouples the 120cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde * stream from the socket, and when the socket is closed, the pending 121cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde * reads never return nor throw and exception. 122cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde * Hence here we use the shutdown method: */ 123a49b4e45faf378e3848c4f6eb468e0a14565aa6cCasper Bonde synchronized (this) { 124a49b4e45faf378e3848c4f6eb468e0a14565aa6cCasper Bonde if (mSocket != null) { 125a49b4e45faf378e3848c4f6eb468e0a14565aa6cCasper Bonde try { 126a49b4e45faf378e3848c4f6eb468e0a14565aa6cCasper Bonde mSocket.shutdownOutput(); 127a49b4e45faf378e3848c4f6eb468e0a14565aa6cCasper Bonde } catch (IOException e) {} 128a49b4e45faf378e3848c4f6eb468e0a14565aa6cCasper Bonde try { 129a49b4e45faf378e3848c4f6eb468e0a14565aa6cCasper Bonde mSocket.shutdownInput(); 130a49b4e45faf378e3848c4f6eb468e0a14565aa6cCasper Bonde } catch (IOException e) {} 131a49b4e45faf378e3848c4f6eb468e0a14565aa6cCasper Bonde try { 132a49b4e45faf378e3848c4f6eb468e0a14565aa6cCasper Bonde mSocket.close(); 133a49b4e45faf378e3848c4f6eb468e0a14565aa6cCasper Bonde } catch (IOException ex) { 134a49b4e45faf378e3848c4f6eb468e0a14565aa6cCasper Bonde if (VERBOSE) Log.e(TAG,"Uncaught exception", ex); 135a49b4e45faf378e3848c4f6eb468e0a14565aa6cCasper Bonde } finally { 136a49b4e45faf378e3848c4f6eb468e0a14565aa6cCasper Bonde mSocket = null; 137a49b4e45faf378e3848c4f6eb468e0a14565aa6cCasper Bonde } 138cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde } 139cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde } 140cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde } 141cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde 142cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde /** 143cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde * Read the message into buffer 144cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde * @param is 145cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde * @param buffer 146cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde * @return the length of the message 147cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde * @throws IOException 148cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde */ 149cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde private static int readMessage(InputStream is, byte[] buffer) throws IOException { 150cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde int countRead; 151cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde int offset; 152cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde int remaining; 153cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde int messageLength; 154cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde 155cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde // Read in the length of the message 156cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde offset = 0; 157cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde remaining = 4; 158cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde do { 159cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde countRead = is.read(buffer, offset, remaining); 160cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde 161cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde if (countRead < 0 ) { 162cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde Log.e(TAG, "Hit EOS reading message length"); 163cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde return -1; 164cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde } 165cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde 166cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde offset += countRead; 167cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde remaining -= countRead; 168cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde } while (remaining > 0); 169cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde 170cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde messageLength = ((buffer[0] & 0xff) << 24) 171cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde | ((buffer[1] & 0xff) << 16) 172cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde | ((buffer[2] & 0xff) << 8) 173cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde | (buffer[3] & 0xff); 174bbb071e6d73df46230ec654e3066a46f6e35a88dCasper Bonde if (VERBOSE) Log.e(TAG,"Message length found to be: "+messageLength); 175cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde // Read the message 176cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde offset = 0; 177cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde remaining = messageLength; 178cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde do { 179cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde countRead = is.read(buffer, offset, remaining); 180cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde 181cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde if (countRead < 0 ) { 182cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde Log.e(TAG, "Hit EOS reading message. messageLength=" + messageLength 183cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde + " remaining=" + remaining); 184cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde return -1; 185cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde } 186cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde 187cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde offset += countRead; 188cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde remaining -= countRead; 189cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde } while (remaining > 0); 190cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde 191cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde return messageLength; 192cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde } 193cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde 194cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde /** 195cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde * The RIL reader thread. Will handle open of the RIL-BT socket, and notify 196cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde * SapServer when done. 197cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde */ 198cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde @Override 199cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde public void run() { 200cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde 201cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde try { 202bbb071e6d73df46230ec654e3066a46f6e35a88dCasper Bonde if (VERBOSE) Log.i(TAG, "Starting RilBtReceiverThread..."); 203cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde 204cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde mSocket = openRilBtSocket(); 205cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde mRilBtInStream = mSocket.getInputStream(); 206cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde mRilBtOutStream = CodedOutputStreamMicro.newInstance(mSocket.getOutputStream()); 207cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde 208cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde // Notify the SapServer that we have connected to the RilBtSocket 209a49b4e45faf378e3848c4f6eb468e0a14565aa6cCasper Bonde sendRilConnectMessage(); 210cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde 211cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde // The main loop - read messages and forward to SAP server 212cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde for (;;) { 213cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde SapMessage sapMsg = null; 214cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde MsgHeader rilMsg; 215cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde 216bbb071e6d73df46230ec654e3066a46f6e35a88dCasper Bonde if (VERBOSE) Log.i(TAG, "Waiting for incoming message..."); 217bbb071e6d73df46230ec654e3066a46f6e35a88dCasper Bonde int length = readMessage(mRilBtInStream, buffer); 218bbb071e6d73df46230ec654e3066a46f6e35a88dCasper Bonde 219bbb071e6d73df46230ec654e3066a46f6e35a88dCasper Bonde SapService.notifyUpdateWakeLock(mSapServiceHandler); 220bbb071e6d73df46230ec654e3066a46f6e35a88dCasper Bonde 221a49b4e45faf378e3848c4f6eb468e0a14565aa6cCasper Bonde if (length == -1) { 222a49b4e45faf378e3848c4f6eb468e0a14565aa6cCasper Bonde if (DEBUG) Log.i(TAG, "EOF reached - closing down."); 223a49b4e45faf378e3848c4f6eb468e0a14565aa6cCasper Bonde break; 224a49b4e45faf378e3848c4f6eb468e0a14565aa6cCasper Bonde } 225a49b4e45faf378e3848c4f6eb468e0a14565aa6cCasper Bonde 226bbb071e6d73df46230ec654e3066a46f6e35a88dCasper Bonde CodedInputStreamMicro msgStream = 227bbb071e6d73df46230ec654e3066a46f6e35a88dCasper Bonde CodedInputStreamMicro.newInstance(buffer, 0, length); 228cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde 229cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde rilMsg = MsgHeader.parseFrom(msgStream); 230cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde 231bbb071e6d73df46230ec654e3066a46f6e35a88dCasper Bonde if (VERBOSE) Log.i(TAG, "Message received."); 232cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde 233cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde sapMsg = SapMessage.newInstance(rilMsg); 234cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde 235bbb071e6d73df46230ec654e3066a46f6e35a88dCasper Bonde if (sapMsg != null && sapMsg.getMsgType() != SapMessage.INVALID_VALUE) 236cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde { 237bbb071e6d73df46230ec654e3066a46f6e35a88dCasper Bonde if (sapMsg.getMsgType() < SapMessage.ID_RIL_BASE) { 238cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde sendClientMessage(sapMsg); 239cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde } else { 240cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde sendRilIndMessage(sapMsg); 241cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde } 242cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde } // else simply ignore it 243cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde } 244a49b4e45faf378e3848c4f6eb468e0a14565aa6cCasper Bonde 245cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde } catch (IOException e) { 246a49b4e45faf378e3848c4f6eb468e0a14565aa6cCasper Bonde notifyShutdown(); /* Only needed in case of a connection error */ 247cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde Log.i(TAG, "'" + SOCKET_NAME_RIL_BT + "' socket inputStream closed", e); 248a49b4e45faf378e3848c4f6eb468e0a14565aa6cCasper Bonde 249a49b4e45faf378e3848c4f6eb468e0a14565aa6cCasper Bonde } finally { 250cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde Log.i(TAG, "Disconnected from '" + SOCKET_NAME_RIL_BT + "' socket"); 251cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde } 252cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde } 253cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde 254cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde /** 255a49b4e45faf378e3848c4f6eb468e0a14565aa6cCasper Bonde * Notify SapServer that the RIL socket is connected 256a49b4e45faf378e3848c4f6eb468e0a14565aa6cCasper Bonde */ 257a49b4e45faf378e3848c4f6eb468e0a14565aa6cCasper Bonde private void sendRilConnectMessage() { 258a49b4e45faf378e3848c4f6eb468e0a14565aa6cCasper Bonde if (mSapServerMsgHandler != null) { 259a49b4e45faf378e3848c4f6eb468e0a14565aa6cCasper Bonde mSapServerMsgHandler.sendEmptyMessage(SapServer.SAP_MSG_RIL_CONNECT); 260a49b4e45faf378e3848c4f6eb468e0a14565aa6cCasper Bonde } 261a49b4e45faf378e3848c4f6eb468e0a14565aa6cCasper Bonde } 262a49b4e45faf378e3848c4f6eb468e0a14565aa6cCasper Bonde 263a49b4e45faf378e3848c4f6eb468e0a14565aa6cCasper Bonde /** 264a49b4e45faf378e3848c4f6eb468e0a14565aa6cCasper Bonde * Send reply (solicited) message from the RIL to the Sap Server Handler Thread 265cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde * @param sapMsg The message to send 266cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde */ 267cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde private void sendClientMessage(SapMessage sapMsg) { 268cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde Message newMsg = mSapServerMsgHandler.obtainMessage(SapServer.SAP_MSG_RFC_REPLY, sapMsg); 269cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde mSapServerMsgHandler.sendMessage(newMsg); 270cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde } 271cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde 272a49b4e45faf378e3848c4f6eb468e0a14565aa6cCasper Bonde /** 273a49b4e45faf378e3848c4f6eb468e0a14565aa6cCasper Bonde * Send a shutdown signal to SapServer to indicate the 274a49b4e45faf378e3848c4f6eb468e0a14565aa6cCasper Bonde */ 275a49b4e45faf378e3848c4f6eb468e0a14565aa6cCasper Bonde private void sendShutdownMessage() { 276a49b4e45faf378e3848c4f6eb468e0a14565aa6cCasper Bonde if (mSapServerMsgHandler != null) { 277a49b4e45faf378e3848c4f6eb468e0a14565aa6cCasper Bonde mSapServerMsgHandler.sendEmptyMessage(SapServer.SAP_RIL_SOCK_CLOSED); 278a49b4e45faf378e3848c4f6eb468e0a14565aa6cCasper Bonde } 279a49b4e45faf378e3848c4f6eb468e0a14565aa6cCasper Bonde } 280a49b4e45faf378e3848c4f6eb468e0a14565aa6cCasper Bonde 281a49b4e45faf378e3848c4f6eb468e0a14565aa6cCasper Bonde /** 282a49b4e45faf378e3848c4f6eb468e0a14565aa6cCasper Bonde * Send indication (unsolicited) message from RIL to the Sap Server Handler Thread 283a49b4e45faf378e3848c4f6eb468e0a14565aa6cCasper Bonde * @param sapMsg The message to send 284a49b4e45faf378e3848c4f6eb468e0a14565aa6cCasper Bonde */ 285cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde private void sendRilIndMessage(SapMessage sapMsg) { 286cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde Message newMsg = mSapServerMsgHandler.obtainMessage(SapServer.SAP_MSG_RIL_IND, sapMsg); 287cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde mSapServerMsgHandler.sendMessage(newMsg); 288cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde } 289cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde 290cee0d1b1f13b4401a895be650605fa307e70bdb6Casper Bonde} 291