blob: 5520615b5c544a5d5f983cf951cefe290ea7fdf2 [file] [log] [blame]
nxpandroid64fd68c2015-09-23 16:45:15 +05301/*
2 * Copyright (C) 2010 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
17package com.android.nfc.ndefpush;
18
19import android.util.Log;
20
21import android.nfc.NdefMessage;
22import android.nfc.FormatException;
23
24import java.io.ByteArrayInputStream;
25import java.io.DataInputStream;
26import java.io.ByteArrayOutputStream;
27import java.io.DataOutputStream;
28
29/**
30 * Implementation of the NDEF Push Protocol.
31 */
32public class NdefPushProtocol {
33 public static final byte ACTION_IMMEDIATE = (byte) 0x01;
34 public static final byte ACTION_BACKGROUND = (byte) 0x02;
35
36 private static final String TAG = "NdefMessageSet";
37 private static final byte VERSION = 1;
38
39 private int mNumMessages;
40 private byte[] mActions;
41 private NdefMessage[] mMessages;
42
43 public NdefPushProtocol(NdefMessage msg, byte action) {
44 mNumMessages = 1;
45 mActions = new byte[1];
46 mActions[0] = action;
47 mMessages = new NdefMessage[1];
48 mMessages[0] = msg;
49 }
50
51 public NdefPushProtocol(byte[] actions, NdefMessage[] messages) {
52 if (actions.length != messages.length || actions.length == 0) {
53 throw new IllegalArgumentException(
54 "actions and messages must be the same size and non-empty");
55 }
56
57 // Keep a copy of these arrays
58 int numMessages = actions.length;
59 mActions = new byte[numMessages];
60 System.arraycopy(actions, 0, mActions, 0, numMessages);
61 mMessages = new NdefMessage[numMessages];
62 System.arraycopy(messages, 0, mMessages, 0, numMessages);
63 mNumMessages = numMessages;
64 }
65
66 public NdefPushProtocol(byte[] data) throws FormatException {
67 ByteArrayInputStream buffer = new ByteArrayInputStream(data);
68 DataInputStream input = new DataInputStream(buffer);
69
70 // Check version of protocol
71 byte version;
72 try {
73 version = input.readByte();
74 } catch (java.io.IOException e) {
75 Log.w(TAG, "Unable to read version");
76 throw new FormatException("Unable to read version");
77 }
78
79 if(version != VERSION) {
80 Log.w(TAG, "Got version " + version + ", expected " + VERSION);
81 throw new FormatException("Got version " + version + ", expected " + VERSION);
82 }
83
84 // Read numMessages
85 try {
86 mNumMessages = input.readInt();
87 } catch(java.io.IOException e) {
88 Log.w(TAG, "Unable to read numMessages");
89 throw new FormatException("Error while parsing NdefMessageSet");
90 }
91 if(mNumMessages == 0) {
92 Log.w(TAG, "No NdefMessage inside NdefMessageSet packet");
93 throw new FormatException("Error while parsing NdefMessageSet");
94 }
95
96 // Read actions and messages
97 mActions = new byte[mNumMessages];
98 mMessages = new NdefMessage[mNumMessages];
99 for(int i = 0; i < mNumMessages; i++) {
100 // Read action
101 try {
102 mActions[i] = input.readByte();
103 } catch(java.io.IOException e) {
104 Log.w(TAG, "Unable to read action for message " + i);
105 throw new FormatException("Error while parsing NdefMessageSet");
106 }
107 // Read message length
108 int length;
109 try {
110 length = input.readInt();
111 } catch(java.io.IOException e) {
112 Log.w(TAG, "Unable to read length for message " + i);
113 throw new FormatException("Error while parsing NdefMessageSet");
114 }
115 byte[] bytes = new byte[length];
116 // Read message
117 int lengthRead;
118 try {
119 lengthRead = input.read(bytes);
120 } catch(java.io.IOException e) {
121 Log.w(TAG, "Unable to read bytes for message " + i);
122 throw new FormatException("Error while parsing NdefMessageSet");
123 }
124 if(length != lengthRead) {
125 Log.w(TAG, "Read " + lengthRead + " bytes but expected " +
126 length);
127 throw new FormatException("Error while parsing NdefMessageSet");
128 }
129 // Create and store NdefMessage
130 try {
131 mMessages[i] = new NdefMessage(bytes);
132 } catch(FormatException e) {
133 throw e;
134 }
135 }
136 }
137
138 public NdefMessage getImmediate() {
139 // Find and return the first immediate message
140 for(int i = 0; i < mNumMessages; i++) {
141 if(mActions[i] == ACTION_IMMEDIATE) {
142 return mMessages[i];
143 }
144 }
145 return null;
146 }
147
148 public byte[] toByteArray() {
149 ByteArrayOutputStream buffer = new ByteArrayOutputStream(1024);
150 DataOutputStream output = new DataOutputStream(buffer);
151
152 try {
153 output.writeByte(VERSION);
154 output.writeInt(mNumMessages);
155 for(int i = 0; i < mNumMessages; i++) {
156 output.writeByte(mActions[i]);
157 byte[] bytes = mMessages[i].toByteArray();
158 output.writeInt(bytes.length);
159 output.write(bytes);
160 }
161 } catch(java.io.IOException e) {
162 return null;
163 }
164
165 return buffer.toByteArray();
166 }
167}