Home | History | Annotate | Download | only in handover
      1 /*
      2  * Copyright (C) 2012 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 package com.android.nfc.handover;
     17 
     18 import android.nfc.FormatException;
     19 import android.nfc.NdefMessage;
     20 import android.util.Log;
     21 
     22 import com.android.nfc.LlcpException;
     23 import com.android.nfc.NfcService;
     24 import com.android.nfc.DeviceHost.LlcpSocket;
     25 
     26 import java.io.ByteArrayOutputStream;
     27 import java.io.IOException;
     28 import java.util.Arrays;
     29 
     30 public final class HandoverClient {
     31     private static final String TAG = "HandoverClient";
     32     private static final int MIU = 128;
     33     // Max NDEF length to receive for Hr/Hs messages
     34     private static final boolean DBG = false;
     35 
     36     public NdefMessage sendHandoverRequest(NdefMessage msg) {
     37         if (msg == null) return null;
     38 
     39         NfcService service = NfcService.getInstance();
     40 
     41         LlcpSocket sock = null;
     42         int offset = 0;
     43         byte[] buffer = msg.toByteArray();
     44         ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
     45 
     46         try {
     47             sock = service.createLlcpSocket(0, MIU, 1, 1024);
     48             if (sock == null) {
     49                 throw new IOException("Could not connect to socket.");
     50             }
     51             if (DBG) Log.d(TAG, "about to connect to service " +
     52                     HandoverServer.HANDOVER_SERVICE_NAME);
     53             sock.connectToService(HandoverServer.HANDOVER_SERVICE_NAME);
     54 
     55             int remoteMiu = sock.getRemoteMiu();
     56             if (DBG) Log.d(TAG, "about to send a " + buffer.length + " byte message");
     57             while (offset < buffer.length) {
     58                 int length = Math.min(buffer.length - offset, remoteMiu);
     59                 byte[] tmpBuffer = Arrays.copyOfRange(buffer, offset, offset+length);
     60                 if (DBG) Log.d(TAG, "about to send a " + length + " byte packet");
     61                 sock.send(tmpBuffer);
     62                 offset += length;
     63             }
     64 
     65             // Now, try to read back the SNEP response
     66             byte[] partial = new byte[sock.getLocalMiu()];
     67             NdefMessage handoverSelectMsg = null;
     68             while (true) {
     69                 int size = sock.receive(partial);
     70                 if (size < 0) {
     71                     break;
     72                 }
     73                 byteStream.write(partial, 0, size);
     74                 try {
     75                     handoverSelectMsg = new NdefMessage(byteStream.toByteArray());
     76                     // If we get here, message is complete
     77                     break;
     78                 } catch (FormatException e) {
     79                     // Ignore, and try to fetch more bytes
     80                 }
     81             }
     82             return handoverSelectMsg;
     83         } catch (IOException e) {
     84             if (DBG) Log.d(TAG, "couldn't connect to handover service");
     85         } catch (LlcpException e) {
     86             if (DBG) Log.d(TAG, "couldn't connect to handover service");
     87         } finally {
     88             if (sock != null) {
     89                 try {
     90                     if (DBG) Log.d(TAG, "about to close");
     91                     sock.close();
     92                 } catch (IOException e) {
     93                     // Ignore
     94                 }
     95             }
     96             try {
     97                 byteStream.close();
     98             } catch (IOException e) {
     99                 // Ignore
    100             }
    101         }
    102         return null;
    103     }
    104 }
    105