• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 NXP Semiconductors
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.sneptest;
17 
18 import android.content.Context;
19 import android.nfc.NdefMessage;
20 import android.util.Log;
21 
22 import com.android.nfc.DeviceHost.LlcpSocket;
23 import com.android.nfc.DtaServiceConnector;
24 import com.android.nfc.LlcpException;
25 import com.android.nfc.NfcService;
26 import com.android.nfc.snep.SnepException;
27 import com.android.nfc.snep.SnepMessage;
28 import com.android.nfc.snep.SnepMessenger;
29 
30 import java.io.IOException;
31 import java.io.UnsupportedEncodingException;
32 
33 public final class DtaSnepClient {
34     private static final String TAG = "DtaSnepClient";
35     private static final boolean DBG = true;
36     private static final int DEFAULT_ACCEPTABLE_LENGTH = 1024;
37     private static final int DEFAULT_MIU = 128;
38     private static final int DEFAULT_RWSIZE = 1;
39     private static final int DEFAULT_PORT = 63;
40     private static final String SNEP_SERVICE_NAME = "urn:nfc:sn:snep";
41     private static final String DEFAULT_SERVICE_NAME = SNEP_SERVICE_NAME;
42     private final Object mTransmissionLock = new Object();
43 
44     private int mState = DISCONNECTED;
45     private final int mAcceptableLength;
46     private final int mFragmentLength;
47     private final int mMiu;
48     private final int mPort;
49     private final int mRwSize;
50     private final String mServiceName;
51     public static int mTestCaseId;
52 
53     private static final int DISCONNECTED = 0;
54     private static final int CONNECTING = 1;
55     private static final int CONNECTED = 2;
56 
57     SnepMessenger mMessenger = null;
58 
DtaSnepClient()59     public DtaSnepClient() {
60         mServiceName = DEFAULT_SERVICE_NAME;
61         mPort = DEFAULT_PORT;
62         mAcceptableLength = DEFAULT_ACCEPTABLE_LENGTH;
63         mFragmentLength = -1;
64         mMiu = DEFAULT_MIU;
65         mRwSize = DEFAULT_RWSIZE;
66     }
67 
DtaSnepClient(String serviceName, int miu, int rwSize, int testCaseId)68     public DtaSnepClient(String serviceName, int miu, int rwSize, int testCaseId) {
69         mServiceName = serviceName;
70         mPort = -1;
71         mAcceptableLength = DEFAULT_ACCEPTABLE_LENGTH;
72         mFragmentLength = -1;
73         mMiu = miu;
74         mRwSize = rwSize;
75         mTestCaseId = testCaseId;
76     }
77 
DtaClientOperations(Context mContext)78     public void DtaClientOperations(Context mContext) {
79         DtaServiceConnector dtaServiceConnector=new DtaServiceConnector(mContext);
80         dtaServiceConnector.bindService();
81         if (DBG) Log.d(TAG, "Connecting remote server");
82         try {
83             connect();
84         } catch(IOException e) {
85             Log.e(TAG, "Error connecting remote server");
86         }
87         switch(mTestCaseId) {
88            //TC_C_BIT_BV_01
89            case 1:
90            {
91                try {
92                    if (DBG) Log.d(TAG, "PUT Small Ndef Data");
93                    put(SnepMessage.getSmallNdef());
94                    dtaServiceConnector.sendMessage(SnepMessage.getSmallNdef().toString());
95                } catch (UnsupportedEncodingException e) {
96                      e.printStackTrace();
97                } catch (IOException e) {
98                      e.printStackTrace();
99                }
100                close();
101            }
102            break;
103            //TC_C_BIT_BI_01_0
104            case 2:
105            {
106                try {
107                    if (DBG) Log.d(TAG, "PUT Small Ndef Data");
108                    put(SnepMessage.getSmallNdef());
109                    dtaServiceConnector.sendMessage(SnepMessage.getSmallNdef().toString());
110                } catch (UnsupportedEncodingException e) {
111                    e.printStackTrace();
112                } catch (IOException e) {
113                    e.printStackTrace();
114                }
115                close();
116            }
117            break;
118            //TC_C_BIT_BI_01_1
119            case 3:
120            {
121                try {
122                    if (DBG) Log.d(TAG, "PUT Small Ndef Data");
123                    put(SnepMessage.getSmallNdef());
124                    dtaServiceConnector.sendMessage(SnepMessage.getSmallNdef().toString());
125                } catch (UnsupportedEncodingException e) {
126                    e.printStackTrace();
127                } catch (IOException e) {
128                    e.printStackTrace();
129                }
130                close();
131            }
132            break;
133            //TC_C_PUT_BV_01
134            case 4:
135            {
136                try {
137                    if (DBG) Log.d(TAG, "PUT Small Ndef Data");
138                    put(SnepMessage.getSmallNdef());
139                    dtaServiceConnector.sendMessage(SnepMessage.getSmallNdef().toString());
140                } catch (UnsupportedEncodingException e) {
141                    e.printStackTrace();
142                } catch (IOException e) {
143                    e.printStackTrace();
144                }
145                close();
146            }
147            break;
148            //TC_C_PUT_BV_02
149            case 5:
150            {
151                try {
152                    if (DBG) Log.d(TAG, "PUT Large Ndef Data");
153                    put(SnepMessage.getLargeNdef());
154                    dtaServiceConnector.sendMessage(SnepMessage.getLargeNdef().toString());
155                } catch (UnsupportedEncodingException e) {
156                    e.printStackTrace();
157                } catch (IOException e) {
158                    e.printStackTrace();
159                }
160                close();
161            }
162            break;
163            //TC_C_PUT_BI_01
164            case 6:
165            {
166                try {
167                    if (DBG) Log.d(TAG, "PUT Large Ndef Data");
168                    put(SnepMessage.getLargeNdef());
169                    dtaServiceConnector.sendMessage(SnepMessage.getLargeNdef().toString());
170                } catch (UnsupportedEncodingException e) {
171                    e.printStackTrace();
172                } catch (IOException e) {
173                    e.printStackTrace();
174                }
175                close();
176            }
177            break;
178            //TC_C_GET_BV_01
179            case 7:
180            {
181                try {
182                    if (DBG) Log.d(TAG, "GET Ndef Message");
183                    get(SnepMessage.getSmallNdef());
184                    dtaServiceConnector.sendMessage(SnepMessage.getSmallNdef().toString());
185                } catch (UnsupportedEncodingException e) {
186                    e.printStackTrace();
187                } catch (IOException e) {
188                    e.printStackTrace();
189                }
190                close();
191            }
192            break;
193            //TC_C_GET_BV_02
194            case 8:
195            {
196                try {
197                    if (DBG) Log.d(TAG, "GET Ndef Message");
198                    get(SnepMessage.getSmallNdef());
199                    dtaServiceConnector.sendMessage(SnepMessage.getSmallNdef().toString());
200                } catch (UnsupportedEncodingException e) {
201                    e.printStackTrace();
202                } catch (IOException e) {
203                    e.printStackTrace();
204                }
205                close();
206            }
207            break;
208            //TC_C_GET_BV_03
209            case 9:
210            {
211                try {
212                    if (DBG) Log.d(TAG, "GET Ndef Message");
213                    get(SnepMessage.getSmallNdef());
214                    dtaServiceConnector.sendMessage(SnepMessage.getSmallNdef().toString());
215                } catch (UnsupportedEncodingException e) {
216                    e.printStackTrace();
217                } catch (IOException e) {
218                    e.printStackTrace();
219                }
220                close();
221            }
222            break;
223            default:
224                if (DBG) Log.d(TAG, "Unknown test case");
225         }
226     }
227 
put(NdefMessage msg)228     public void put(NdefMessage msg) throws IOException {
229         SnepMessenger messenger;
230         synchronized (this) {
231             if (mState != CONNECTED) {
232                 throw new IOException("Socket not connected.");
233             }
234             messenger = mMessenger;
235         }
236 
237         synchronized (mTransmissionLock) {
238             try {
239                 messenger.sendMessage(SnepMessage.getPutRequest(msg));
240                 messenger.getMessage();
241             } catch (SnepException e) {
242                 throw new IOException(e);
243             }
244         }
245     }
246 
get(NdefMessage msg)247     public SnepMessage get(NdefMessage msg) throws IOException {
248         SnepMessenger messenger;
249         synchronized (this) {
250             if (mState != CONNECTED) {
251                 throw new IOException("Socket not connected.");
252             }
253             messenger = mMessenger;
254         }
255 
256         synchronized (mTransmissionLock) {
257             try {
258                 messenger.sendMessage(SnepMessage.getGetRequest(mAcceptableLength, msg));
259                 return messenger.getMessage();
260             } catch (SnepException e) {
261                 throw new IOException(e);
262             }
263         }
264     }
265 
connect()266     public void connect() throws IOException {
267         synchronized (this) {
268             if (mState != DISCONNECTED) {
269                 throw new IOException("Socket already in use.");
270             }
271             mState = CONNECTING;
272         }
273 
274         LlcpSocket socket = null;
275         SnepMessenger messenger;
276         try {
277             if (DBG) Log.d(TAG, "about to create socket");
278             // Connect to the snep server on the remote side
279             socket = NfcService.getInstance().createLlcpSocket(0, mMiu, mRwSize, 1024);
280             if (socket == null) {
281                 throw new IOException("Could not connect to socket.");
282             }
283             if (mPort == -1) {
284                 if (DBG) Log.d(TAG, "about to connect to service " + mServiceName);
285                 socket.connectToService(mServiceName);
286             } else {
287                 if (DBG) Log.d(TAG, "about to connect to port " + mPort);
288                 socket.connectToSap(mPort);
289             }
290             int miu = socket.getRemoteMiu();
291             int fragmentLength = (mFragmentLength == -1) ?  miu : Math.min(miu, mFragmentLength);
292             messenger = new SnepMessenger(true, socket, fragmentLength);
293         } catch (LlcpException e) {
294             synchronized (this) {
295                 mState = DISCONNECTED;
296             }
297             throw new IOException("Could not connect to socket");
298         } catch (IOException e) {
299             if (socket != null) {
300                 try {
301                     socket.close();
302                 } catch (IOException e2) {}
303             }
304             synchronized (this) {
305                 mState = DISCONNECTED;
306             }
307             throw new IOException("Failed to connect to socket");
308         }
309 
310         synchronized (this) {
311             mMessenger = messenger;
312             mState = CONNECTED;
313         }
314     }
315 
close()316     public void close() {
317         synchronized (this) {
318             if (mMessenger != null) {
319                try {
320                    mMessenger.close();
321                } catch (IOException e) {
322                    // ignore
323                } finally {
324                    mMessenger = null;
325                    mState = DISCONNECTED;
326                }
327             }
328         }
329     }
330 }
331