NdefPushClient.java revision bcccb386fe1dc20401b88ab0b0e493a8dbe7615c
157d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton/*
257d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton * Copyright (C) 2010 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
1757d376f1ee1a3939977b95759525585abb9601fbJeff Hamiltonpackage com.android.nfc.mytag;
1857d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton
1957d376f1ee1a3939977b95759525585abb9601fbJeff Hamiltonimport com.android.internal.nfc.LlcpException;
2057d376f1ee1a3939977b95759525585abb9601fbJeff Hamiltonimport com.android.internal.nfc.LlcpSocket;
2157d376f1ee1a3939977b95759525585abb9601fbJeff Hamiltonimport com.android.nfc.NfcService;
2257d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton
2357d376f1ee1a3939977b95759525585abb9601fbJeff Hamiltonimport android.content.BroadcastReceiver;
2457d376f1ee1a3939977b95759525585abb9601fbJeff Hamiltonimport android.content.Context;
2557d376f1ee1a3939977b95759525585abb9601fbJeff Hamiltonimport android.content.Intent;
2657d376f1ee1a3939977b95759525585abb9601fbJeff Hamiltonimport android.content.IntentFilter;
2757d376f1ee1a3939977b95759525585abb9601fbJeff Hamiltonimport android.nfc.NdefMessage;
2857d376f1ee1a3939977b95759525585abb9601fbJeff Hamiltonimport android.nfc.NfcAdapter;
2957d376f1ee1a3939977b95759525585abb9601fbJeff Hamiltonimport android.os.AsyncTask;
3057d376f1ee1a3939977b95759525585abb9601fbJeff Hamiltonimport android.util.Log;
3157d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton
3257d376f1ee1a3939977b95759525585abb9601fbJeff Hamiltonimport java.io.IOException;
3357d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton
3457d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton/**
3557d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton * Simple client to push the local NDEF message to a server on the remote side of an
3657d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton * LLCP connection. The message is set via {@link NfcAdapter#setLocalNdefMessage}.
3757d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton */
3857d376f1ee1a3939977b95759525585abb9601fbJeff Hamiltonpublic class MyTagClient extends BroadcastReceiver {
3957d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton    private static final String TAG = "MyTagClient";
40bcccb386fe1dc20401b88ab0b0e493a8dbe7615cSylvain Fonteneau    private static final int MIU = 128;
4157d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton    private static final boolean DBG = true;
4257d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton
4357d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton    public MyTagClient(Context context) {
4457d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton        context.registerReceiver(this, new IntentFilter(NfcAdapter.ACTION_LLCP_LINK_STATE_CHANGED));
4557d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton    }
4657d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton
4757d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton    @Override
4857d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton    public void onReceive(Context context, Intent intent) {
49d4c32dbf41b379b6c7102d5b53a09bc5ce9760e4Jeff Hamilton        int linkState = intent.getIntExtra(NfcAdapter.EXTRA_LLCP_LINK_STATE_CHANGED,
50d4c32dbf41b379b6c7102d5b53a09bc5ce9760e4Jeff Hamilton                NfcAdapter.LLCP_LINK_STATE_DEACTIVATED);
51d4c32dbf41b379b6c7102d5b53a09bc5ce9760e4Jeff Hamilton        if (linkState != NfcAdapter.LLCP_LINK_STATE_ACTIVATED) {
52d4c32dbf41b379b6c7102d5b53a09bc5ce9760e4Jeff Hamilton            // The link was torn down, ignore
53d4c32dbf41b379b6c7102d5b53a09bc5ce9760e4Jeff Hamilton            return;
54d4c32dbf41b379b6c7102d5b53a09bc5ce9760e4Jeff Hamilton        }
55d4c32dbf41b379b6c7102d5b53a09bc5ce9760e4Jeff Hamilton
5657d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton        if (DBG) Log.d(TAG, "LLCP connection up and running");
5757d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton        NfcAdapter adapter = NfcAdapter.getDefaultAdapter();
5857d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton        NdefMessage msg = adapter.getLocalNdefMessage();
5957d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton        if (msg == null) {
6057d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton            if (DBG) Log.d(TAG, "No MyTag set, exiting");
6157d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton            // Nothing to send to the server
6257d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton            return;
6357d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton        }
6457d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton
6557d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton        new SendAsync().execute(msg);
6657d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton    }
6757d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton
6857d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton    final class SendAsync extends AsyncTask<NdefMessage, Void, Void> {
6957d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton        @Override
7057d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton        public Void doInBackground(NdefMessage... msgs) {
7157d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton            NfcService service = NfcService.getInstance();
7257d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton            NdefMessage msg = msgs[0];
73bcccb386fe1dc20401b88ab0b0e493a8dbe7615cSylvain Fonteneau            byte[] buffer = msg.toByteArray();
74bcccb386fe1dc20401b88ab0b0e493a8dbe7615cSylvain Fonteneau            byte[] tmpBuffer = new byte[MIU];
75bcccb386fe1dc20401b88ab0b0e493a8dbe7615cSylvain Fonteneau            int offset = 0;
7657d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton            try {
7757d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton                if (DBG) Log.d(TAG, "about to create socket");
7857d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton                // Connect to the my tag server on the remote side
79bcccb386fe1dc20401b88ab0b0e493a8dbe7615cSylvain Fonteneau                LlcpSocket sock = service.createLlcpSocket(0, MIU, 1, 1024);
8057d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton                if (DBG) Log.d(TAG, "about to connect");
8157d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton//                sock.connect(MyTagServer.SERVICE_NAME);
8257d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton                sock.connect(0x20);
8357d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton
84bcccb386fe1dc20401b88ab0b0e493a8dbe7615cSylvain Fonteneau                if (DBG) Log.d(TAG, "about to send a " + buffer.length + "-bytes message");
85bcccb386fe1dc20401b88ab0b0e493a8dbe7615cSylvain Fonteneau                while (offset < buffer.length) {
86bcccb386fe1dc20401b88ab0b0e493a8dbe7615cSylvain Fonteneau                    int length = buffer.length - offset;
87bcccb386fe1dc20401b88ab0b0e493a8dbe7615cSylvain Fonteneau                    if (length > tmpBuffer.length) {
88bcccb386fe1dc20401b88ab0b0e493a8dbe7615cSylvain Fonteneau                        length = tmpBuffer.length;
89bcccb386fe1dc20401b88ab0b0e493a8dbe7615cSylvain Fonteneau                    }
90bcccb386fe1dc20401b88ab0b0e493a8dbe7615cSylvain Fonteneau                    System.arraycopy(buffer, offset, tmpBuffer, 0, length);
91bcccb386fe1dc20401b88ab0b0e493a8dbe7615cSylvain Fonteneau                    if (DBG) Log.d(TAG, "about to send a " + length + "-bytes packet");
92bcccb386fe1dc20401b88ab0b0e493a8dbe7615cSylvain Fonteneau                    sock.send(tmpBuffer);
93bcccb386fe1dc20401b88ab0b0e493a8dbe7615cSylvain Fonteneau                    offset += length;
94bcccb386fe1dc20401b88ab0b0e493a8dbe7615cSylvain Fonteneau                }
95bcccb386fe1dc20401b88ab0b0e493a8dbe7615cSylvain Fonteneau
9657d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton                if (DBG) Log.d(TAG, "about to close");
9757d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton                sock.close();
9857d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton
9957d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton            } catch (IOException e) {
10057d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton                Log.e(TAG, "couldn't send tag", e);
10157d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton            } catch (LlcpException e) {
10257d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton                // Most likely the other side doesn't support the my tag protocol
10357d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton                Log.e(TAG, "couldn't send tag", e);
10457d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton            }
10557d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton            return null;
10657d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton        }
10757d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton    }
10857d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton}
109