blob: 03824ccd713636bf831ead11cdbd9b33b3815764 [file] [log] [blame]
nxpandroid64fd68c2015-09-23 16:45:15 +05301/*
2 * Copyright (C) 2011 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.snep;
18
19import com.android.nfc.DeviceHost.LlcpSocket;
20import com.android.nfc.LlcpException;
21import com.android.nfc.NfcService;
22
23import android.nfc.NdefMessage;
24import android.util.Log;
25
26import java.io.IOException;
27
28public final class SnepClient {
29 private static final String TAG = "SnepClient";
30 private static final boolean DBG = false;
31 private static final int DEFAULT_ACCEPTABLE_LENGTH = 100*1024;
32 private static final int DEFAULT_MIU = 128;
33 private static final int DEFAULT_RWSIZE = 1;
34 SnepMessenger mMessenger = null;
35 private final Object mTransmissionLock = new Object();
36
37 private final String mServiceName;
38 private final int mPort;
39 private int mState = DISCONNECTED;
40 private final int mAcceptableLength;
41 private final int mFragmentLength;
42 private final int mMiu;
43 private final int mRwSize;
44
45 private static final int DISCONNECTED = 0;
46 private static final int CONNECTING = 1;
47 private static final int CONNECTED = 2;
48
49 public SnepClient() {
50 mServiceName = SnepServer.DEFAULT_SERVICE_NAME;
51 mPort = SnepServer.DEFAULT_PORT;
52 mAcceptableLength = DEFAULT_ACCEPTABLE_LENGTH;
53 mFragmentLength = -1;
54 mMiu = DEFAULT_MIU;
55 mRwSize = DEFAULT_RWSIZE;
56 }
57
58 public SnepClient(String serviceName) {
59 mServiceName = serviceName;
60 mPort = -1;
61 mAcceptableLength = DEFAULT_ACCEPTABLE_LENGTH;
62 mFragmentLength = -1;
63 mMiu = DEFAULT_MIU;
64 mRwSize = DEFAULT_RWSIZE;
65 }
66
67 public SnepClient(int miu, int rwSize) {
68 mServiceName = SnepServer.DEFAULT_SERVICE_NAME;
69 mPort = SnepServer.DEFAULT_PORT;
70 mAcceptableLength = DEFAULT_ACCEPTABLE_LENGTH;
71 mFragmentLength = -1;
72 mMiu = miu;
73 mRwSize = rwSize;
74 }
75
76 SnepClient(String serviceName, int fragmentLength) {
77 mServiceName = serviceName;
78 mPort = -1;
79 mAcceptableLength = DEFAULT_ACCEPTABLE_LENGTH;
80 mFragmentLength = fragmentLength;
81 mMiu = DEFAULT_MIU;
82 mRwSize = DEFAULT_RWSIZE;
83 }
84
85 SnepClient(String serviceName, int acceptableLength, int fragmentLength) {
86 mServiceName = serviceName;
87 mPort = -1;
88 mAcceptableLength = acceptableLength;
89 mFragmentLength = fragmentLength;
90 mMiu = DEFAULT_MIU;
91 mRwSize = DEFAULT_RWSIZE;
92 }
93
94 public void put(NdefMessage msg) throws IOException {
95 SnepMessenger messenger;
96 synchronized (this) {
97 if (mState != CONNECTED) {
98 throw new IOException("Socket not connected.");
99 }
100 messenger = mMessenger;
101 }
102
103 synchronized (mTransmissionLock) {
104 try {
105 messenger.sendMessage(SnepMessage.getPutRequest(msg));
106 messenger.getMessage();
107 } catch (SnepException e) {
108 throw new IOException(e);
109 }
110 }
111 }
112
113 public SnepMessage get(NdefMessage msg) throws IOException {
114 SnepMessenger messenger;
115 synchronized (this) {
116 if (mState != CONNECTED) {
117 throw new IOException("Socket not connected.");
118 }
119 messenger = mMessenger;
120 }
121
122 synchronized (mTransmissionLock) {
123 try {
124 messenger.sendMessage(SnepMessage.getGetRequest(mAcceptableLength, msg));
125 return messenger.getMessage();
126 } catch (SnepException e) {
127 throw new IOException(e);
128 }
129 }
130 }
131
132 public void connect() throws IOException {
133 synchronized (this) {
134 if (mState != DISCONNECTED) {
135 throw new IOException("Socket already in use.");
136 }
137 mState = CONNECTING;
138 }
139
140 LlcpSocket socket = null;
141 SnepMessenger messenger;
142 try {
143 if (DBG) Log.d(TAG, "about to create socket");
144 // Connect to the snep server on the remote side
145 socket = NfcService.getInstance().createLlcpSocket(0, mMiu, mRwSize, 1024);
146 if (socket == null) {
147 throw new IOException("Could not connect to socket.");
148 }
149 if (mPort == -1) {
150 if (DBG) Log.d(TAG, "about to connect to service " + mServiceName);
151 socket.connectToService(mServiceName);
152 } else {
153 if (DBG) Log.d(TAG, "about to connect to port " + mPort);
154 socket.connectToSap(mPort);
155 }
156 int miu = socket.getRemoteMiu();
157 int fragmentLength = (mFragmentLength == -1) ? miu : Math.min(miu, mFragmentLength);
158 messenger = new SnepMessenger(true, socket, fragmentLength);
159 } catch (LlcpException e) {
160 synchronized (this) {
161 mState = DISCONNECTED;
162 }
163 throw new IOException("Could not connect to socket");
164 } catch (IOException e) {
165 if (socket != null) {
166 try {
167 socket.close();
168 } catch (IOException e2) {
169 }
170 }
171 synchronized (this) {
172 mState = DISCONNECTED;
173 }
174 throw new IOException("Failed to connect to socket");
175 }
176
177 synchronized (this) {
178 mMessenger = messenger;
179 mState = CONNECTED;
180 }
181 }
182
183 public void close() {
184 synchronized (this) {
185 if (mMessenger != null) {
186 try {
187 mMessenger.close();
188 } catch (IOException e) {
189 // ignore
190 } finally {
191 mMessenger = null;
192 mState = DISCONNECTED;
193 }
194 }
195 }
196 }
197}