157d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton/* 22ef360deaff9f17aa72d5749ceee283cc80897afBen Dodson * Copyright (C) 2011 The Android Open Source Project 357d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton * 457d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton * Licensed under the Apache License, Version 2.0 (the "License"); 557d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton * you may not use this file except in compliance with the License. 657d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton * You may obtain a copy of the License at 757d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton * 857d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton * http://www.apache.org/licenses/LICENSE-2.0 957d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton * 1057d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton * Unless required by applicable law or agreed to in writing, software 1157d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton * distributed under the License is distributed on an "AS IS" BASIS, 1257d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1357d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton * See the License for the specific language governing permissions and 1457d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton * limitations under the License. 1557d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton */ 1657d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 17ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamiltonpackage com.android.nfc.ndefpush; 1857d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 194a61d3b45e81c0070538f94747a70a49c78f12faJeff Hamiltonimport com.android.nfc.DeviceHost.LlcpSocket; 204a61d3b45e81c0070538f94747a70a49c78f12faJeff Hamiltonimport com.android.nfc.LlcpException; 214a61d3b45e81c0070538f94747a70a49c78f12faJeff Hamiltonimport com.android.nfc.NfcService; 224a61d3b45e81c0070538f94747a70a49c78f12faJeff Hamilton 232ef360deaff9f17aa72d5749ceee283cc80897afBen Dodsonimport android.nfc.NdefMessage; 242ef360deaff9f17aa72d5749ceee283cc80897afBen Dodsonimport android.util.Log; 252ef360deaff9f17aa72d5749ceee283cc80897afBen Dodson 2657d376f1ee1a3939977b95759525585abb9601fbJeff Hamiltonimport java.io.IOException; 27ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamiltonimport java.util.Arrays; 2857d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 2957d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton/** 3057d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton * Simple client to push the local NDEF message to a server on the remote side of an 312ef360deaff9f17aa72d5749ceee283cc80897afBen Dodson * LLCP connection, using the Android Ndef Push Protocol. 3257d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton */ 332ef360deaff9f17aa72d5749ceee283cc80897afBen Dodsonpublic class NdefPushClient { 34ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton private static final String TAG = "NdefPushClient"; 35bcccb386fe1dc20401b88ab0b0e493a8dbe7615cSylvain Fonteneau private static final int MIU = 128; 3657d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton private static final boolean DBG = true; 3757d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 38d2d5dddf17ac2008547172cd72faa034a89d569bJeff Hamilton public boolean push(NdefMessage msg) { 392ef360deaff9f17aa72d5749ceee283cc80897afBen Dodson NfcService service = NfcService.getInstance(); 402ef360deaff9f17aa72d5749ceee283cc80897afBen Dodson 412ef360deaff9f17aa72d5749ceee283cc80897afBen Dodson // We only handle a single immediate action for now 42d2d5dddf17ac2008547172cd72faa034a89d569bJeff Hamilton NdefPushProtocol proto = new NdefPushProtocol(msg, NdefPushProtocol.ACTION_IMMEDIATE); 43d2d5dddf17ac2008547172cd72faa034a89d569bJeff Hamilton byte[] buffer = proto.toByteArray(); 442ef360deaff9f17aa72d5749ceee283cc80897afBen Dodson int offset = 0; 452ef360deaff9f17aa72d5749ceee283cc80897afBen Dodson int remoteMiu; 462ef360deaff9f17aa72d5749ceee283cc80897afBen Dodson LlcpSocket sock = null; 472ef360deaff9f17aa72d5749ceee283cc80897afBen Dodson try { 482ef360deaff9f17aa72d5749ceee283cc80897afBen Dodson if (DBG) Log.d(TAG, "about to create socket"); 492ef360deaff9f17aa72d5749ceee283cc80897afBen Dodson // Connect to the my tag server on the remote side 502ef360deaff9f17aa72d5749ceee283cc80897afBen Dodson sock = service.createLlcpSocket(0, MIU, 1, 1024); 512ef360deaff9f17aa72d5749ceee283cc80897afBen Dodson if (sock == null) { 522ef360deaff9f17aa72d5749ceee283cc80897afBen Dodson throw new IOException("Could not connect to socket."); 532094515fca0cfa0ac87e9cc260d3953d416afe3eJason parks } 542ef360deaff9f17aa72d5749ceee283cc80897afBen Dodson if (DBG) Log.d(TAG, "about to connect to service " + NdefPushServer.SERVICE_NAME); 554a61d3b45e81c0070538f94747a70a49c78f12faJeff Hamilton sock.connectToService(NdefPushServer.SERVICE_NAME); 562ef360deaff9f17aa72d5749ceee283cc80897afBen Dodson 574a61d3b45e81c0070538f94747a70a49c78f12faJeff Hamilton remoteMiu = sock.getRemoteMiu(); 582ef360deaff9f17aa72d5749ceee283cc80897afBen Dodson if (DBG) Log.d(TAG, "about to send a " + buffer.length + " byte message"); 592ef360deaff9f17aa72d5749ceee283cc80897afBen Dodson while (offset < buffer.length) { 602ef360deaff9f17aa72d5749ceee283cc80897afBen Dodson int length = Math.min(buffer.length - offset, remoteMiu); 612ef360deaff9f17aa72d5749ceee283cc80897afBen Dodson byte[] tmpBuffer = Arrays.copyOfRange(buffer, offset, offset+length); 622ef360deaff9f17aa72d5749ceee283cc80897afBen Dodson if (DBG) Log.d(TAG, "about to send a " + length + " byte packet"); 632ef360deaff9f17aa72d5749ceee283cc80897afBen Dodson sock.send(tmpBuffer); 642ef360deaff9f17aa72d5749ceee283cc80897afBen Dodson offset += length; 6557d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 66d2d5dddf17ac2008547172cd72faa034a89d569bJeff Hamilton return true; 672ef360deaff9f17aa72d5749ceee283cc80897afBen Dodson } catch (IOException e) { 682ef360deaff9f17aa72d5749ceee283cc80897afBen Dodson Log.e(TAG, "couldn't send tag"); 692ef360deaff9f17aa72d5749ceee283cc80897afBen Dodson if (DBG) Log.d(TAG, "exception:", e); 702ef360deaff9f17aa72d5749ceee283cc80897afBen Dodson } catch (LlcpException e) { 712ef360deaff9f17aa72d5749ceee283cc80897afBen Dodson // Most likely the other side doesn't support the my tag protocol 722ef360deaff9f17aa72d5749ceee283cc80897afBen Dodson Log.e(TAG, "couldn't send tag"); 732ef360deaff9f17aa72d5749ceee283cc80897afBen Dodson if (DBG) Log.d(TAG, "exception:", e); 742ef360deaff9f17aa72d5749ceee283cc80897afBen Dodson } finally { 752ef360deaff9f17aa72d5749ceee283cc80897afBen Dodson if (sock != null) { 762094515fca0cfa0ac87e9cc260d3953d416afe3eJason parks try { 772ef360deaff9f17aa72d5749ceee283cc80897afBen Dodson if (DBG) Log.d(TAG, "about to close"); 782ef360deaff9f17aa72d5749ceee283cc80897afBen Dodson sock.close(); 792ef360deaff9f17aa72d5749ceee283cc80897afBen Dodson } catch (IOException e) { 802094515fca0cfa0ac87e9cc260d3953d416afe3eJason parks // Ignore 812094515fca0cfa0ac87e9cc260d3953d416afe3eJason parks } 822094515fca0cfa0ac87e9cc260d3953d416afe3eJason parks } 8357d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 84d2d5dddf17ac2008547172cd72faa034a89d569bJeff Hamilton return false; 8557d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 8657d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton} 87