OSDN Git Service

a0c5f1aee9b34aec87794592b52b33837e21c810
[android-x86/hardware-interfaces.git] / nfc / 1.0 / vts / functional / VtsHalNfcV1_0TargetTest.cpp
1 /*
2  * Copyright (C) 2016 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
17 #define LOG_TAG "nfc_hidl_hal_test"
18 #include <android-base/logging.h>
19
20 #include <android/hardware/nfc/1.0/INfc.h>
21 #include <android/hardware/nfc/1.0/INfcClientCallback.h>
22 #include <android/hardware/nfc/1.0/types.h>
23 #include <hardware/nfc.h>
24
25 #include <gtest/gtest.h>
26 #include <chrono>
27 #include <condition_variable>
28 #include <mutex>
29
30 using ::android::hardware::nfc::V1_0::INfc;
31 using ::android::hardware::nfc::V1_0::INfcClientCallback;
32 using ::android::hardware::nfc::V1_0::NfcEvent;
33 using ::android::hardware::nfc::V1_0::NfcStatus;
34 using ::android::hardware::nfc::V1_0::NfcData;
35 using ::android::hardware::Return;
36 using ::android::hardware::Void;
37 using ::android::hardware::hidl_vec;
38 using ::android::sp;
39
40 /* NCI Commands */
41 #define CORE_RESET_CMD \
42   { 0x20, 0x00, 0x01, 0x00 }
43 #define CORE_RESET_CMD_CONFIG_RESET \
44   { 0x20, 0x00, 0x01, 0x01 }
45 #define CORE_CONN_CREATE_CMD \
46   { 0x20, 0x04, 0x02, 0x01, 0x00 }
47 #define INVALID_COMMAND \
48   { 0x20, 0x00, 0x00 }
49 #define FAULTY_DATA_PACKET \
50   { 0x00, 0x00, 0xFF }
51
52 #define LOOP_BACK_HEADER_SIZE 3
53 #define SYNTAX_ERROR 5
54 #define NUMBER_LOOPS 3922
55 #define VERSION 0x11
56 #define TIMEOUT_PERIOD 5
57
58 // The main test class for NFC HIDL HAL.
59 class NfcHidlTest : public ::testing::Test {
60  public:
61   virtual void SetUp() override {
62     nfc_ = INfc::getService();
63     ASSERT_NE(nfc_, nullptr);
64
65     nfc_cb_ = new NfcClientCallback(*this);
66     ASSERT_NE(nfc_cb_, nullptr);
67
68     count = 0;
69     last_event_ = NfcEvent::ERROR;
70     last_status_ = NfcStatus::FAILED;
71
72     EXPECT_EQ(NfcStatus::OK, nfc_->open(nfc_cb_));
73     // Wait for OPEN_CPLT event
74     EXPECT_EQ(std::cv_status::no_timeout, wait());
75     EXPECT_EQ(NfcEvent::OPEN_CPLT, last_event_);
76     EXPECT_EQ(NfcStatus::OK, last_status_);
77   }
78
79   virtual void TearDown() override {
80     EXPECT_EQ(NfcStatus::OK, nfc_->close());
81     // Wait for CLOSE_CPLT event
82     EXPECT_EQ(std::cv_status::no_timeout, wait());
83     EXPECT_EQ(NfcEvent::CLOSE_CPLT, last_event_);
84     EXPECT_EQ(NfcStatus::OK, last_status_);
85   }
86
87   /* Used as a mechanism to inform the test about data/event callback */
88   inline void notify() {
89     std::unique_lock<std::mutex> lock(mtx);
90     count++;
91     cv.notify_one();
92   }
93
94   /* Test code calls this function to wait for data/event callback */
95   inline std::cv_status wait() {
96     std::unique_lock<std::mutex> lock(mtx);
97
98     std::cv_status status = std::cv_status::no_timeout;
99     auto now = std::chrono::system_clock::now();
100     while (count == 0) {
101       status = cv.wait_until(lock, now + std::chrono::seconds(TIMEOUT_PERIOD));
102       if (status == std::cv_status::timeout) return status;
103     }
104     count--;
105     return status;
106   }
107
108   /* Callback class for data & Event. */
109   class NfcClientCallback : public INfcClientCallback {
110     NfcHidlTest& parent_;
111
112    public:
113     NfcClientCallback(NfcHidlTest& parent) : parent_(parent){};
114
115     virtual ~NfcClientCallback() = default;
116
117     /* sendEvent callback function - Records the Event & Status
118      * and notifies the TEST
119      **/
120     Return<void> sendEvent(NfcEvent event, NfcStatus event_status) override {
121       parent_.last_event_ = event;
122       parent_.last_status_ = event_status;
123       parent_.notify();
124       return Void();
125     };
126
127     /* sendData callback function. Records the data and notifies the TEST*/
128     Return<void> sendData(const NfcData& data) override {
129       size_t size = parent_.last_data_.size();
130       parent_.last_data_.resize(size + 1);
131       parent_.last_data_[size] = data;
132       parent_.notify();
133       return Void();
134     };
135   };
136
137   sp<INfc> nfc_;
138   sp<INfcClientCallback> nfc_cb_;
139   NfcEvent last_event_;
140   NfcStatus last_status_;
141   hidl_vec<NfcData> last_data_;
142
143  private:
144   std::mutex mtx;
145   std::condition_variable cv;
146   int count;
147 };
148
149 // A class for test environment setup (kept since this file is a template).
150 class NfcHidlEnvironment : public ::testing::Environment {
151  public:
152   virtual void SetUp() {}
153   virtual void TearDown() {}
154
155  private:
156 };
157
158 /*
159  * OpenAndClose:
160  * Makes an open call, waits for NfcEvent.OPEN_CPLT
161  * Immediately calls close() and waits for NfcEvent.CLOSE_CPLT
162  * Since open and close calls are a part of SetUp() and TearDown(),
163  * the function definition is intentionally kept empty
164  */
165 TEST_F(NfcHidlTest, OpenAndClose) {}
166
167 /*
168  * WriteCoreReset:
169  * Sends CORE_RESET_CMD
170  * Waits for CORE_RESET_RSP
171  * Checks the status, version number and configuration status
172  */
173 TEST_F(NfcHidlTest, WriteCoreReset) {
174   std::vector<uint8_t> cmd = CORE_RESET_CMD;
175   NfcData data = cmd;
176   EXPECT_EQ(data.size(), nfc_->write(data));
177   // Wait for CORE_RESET_RSP
178   EXPECT_EQ(std::cv_status::no_timeout, wait());
179   EXPECT_EQ(1ul, last_data_.size());
180   EXPECT_EQ(6ul, last_data_[0].size());
181   EXPECT_EQ((int)NfcStatus::OK, last_data_[0][3]);
182   EXPECT_GE(VERSION, last_data_[0][4]);
183   EXPECT_EQ(0ul, last_data_[0][5]);
184 }
185
186 /*
187  * WriteCoreResetConfigReset:
188  * Sends CORE_RESET_CMD_CONFIG_RESET
189  * Waits for CORE_RESET_RSP
190  * Checks the status, version number and configuration status
191  */
192 TEST_F(NfcHidlTest, WriteCoreResetConfigReset) {
193   std::vector<uint8_t> cmd = CORE_RESET_CMD_CONFIG_RESET;
194   NfcData data = cmd;
195   EXPECT_EQ(data.size(), nfc_->write(data));
196   // Wait for CORE_RESET_RSP
197   EXPECT_EQ(std::cv_status::no_timeout, wait());
198   EXPECT_EQ(1ul, last_data_.size());
199   EXPECT_EQ(6ul, last_data_[0].size());
200   EXPECT_EQ((int)NfcStatus::OK, last_data_[0][3]);
201   EXPECT_GE(VERSION, last_data_[0][4]);
202   EXPECT_EQ(1ul, last_data_[0][5]);
203 }
204
205 /*
206  * WriteInvalidCommand:
207  * Sends an invalid command
208  * Waits for response
209  * Checks SYNTAX_ERROR status
210  */
211 TEST_F(NfcHidlTest, WriteInvalidCommand) {
212   // Send an Error Command
213   std::vector<uint8_t> cmd = INVALID_COMMAND;
214   NfcData data = cmd;
215   EXPECT_EQ(data.size(), nfc_->write(data));
216   // Wait for RSP
217   EXPECT_EQ(std::cv_status::no_timeout, wait());
218   EXPECT_EQ(1ul, last_data_.size());
219   EXPECT_EQ(4ul, last_data_[0].size());
220   EXPECT_EQ(SYNTAX_ERROR, last_data_[0][3]);
221 }
222
223 /*
224  * WriteInvalidAndThenValidCommand:
225  * Sends an Faulty Data Packet
226  * Waits for CORE_INTERFACE_ERROR_NTF
227  * Checks SYNTAX_ERROR status
228  * Repeat for 100 times appending 0xFF each time to the packet
229  * Send CORE_CONN_CREATE_CMD for loop-back mode
230  * Check the response
231  */
232 TEST_F(NfcHidlTest, WriteInvalidAndThenValidCommand) {
233   // Send an Error Data Packet
234   std::vector<uint8_t> cmd = FAULTY_DATA_PACKET;
235   NfcData data = cmd;
236   size_t size = data.size();
237
238   for (int i = 0; i < 100; i++) {
239     last_data_.resize(0);
240     data.resize(++size);
241     data[size - 1] = 0xFF;
242     EXPECT_EQ(data.size(), nfc_->write(data));
243     // Wait for CORE_INTERFACE_ERROR_NTF
244     EXPECT_EQ(std::cv_status::no_timeout, wait());
245     EXPECT_EQ(1ul, last_data_.size());
246     EXPECT_EQ(5ul, last_data_[0].size());
247     EXPECT_EQ(0x60, last_data_[0][0]);
248     EXPECT_EQ(0x08, last_data_[0][1]);
249     EXPECT_EQ(0x02, last_data_[0][2]);
250     EXPECT_EQ(SYNTAX_ERROR, last_data_[0][3]);
251   }
252
253   cmd = CORE_CONN_CREATE_CMD;
254   data = cmd;
255   last_data_.resize(0);
256   EXPECT_EQ(data.size(), nfc_->write(data));
257   // Wait for CORE_CONN_CREATE_RSP
258   EXPECT_EQ(std::cv_status::no_timeout, wait());
259   EXPECT_EQ(1ul, last_data_.size());
260   EXPECT_EQ(7ul, last_data_[0].size());
261   EXPECT_EQ((int)NfcStatus::OK, last_data_[0][3]);
262 }
263 /*
264  * Bandwidth:
265  * Sets the loop-back mode using CORE_CONN_CREATE_CMD
266  * Sends max payload size data
267  * Waits for the response
268  * Checks the data received
269  * Repeat to send total of 1Mb data
270  */
271 TEST_F(NfcHidlTest, Bandwidth) {
272   std::vector<uint8_t> cmd = CORE_CONN_CREATE_CMD;
273   NfcData data = cmd;
274   EXPECT_EQ(data.size(), nfc_->write(data));
275   // Wait for CORE_CONN_CREATE_RSP
276   EXPECT_EQ(std::cv_status::no_timeout, wait());
277   EXPECT_EQ(1ul, last_data_.size());
278   EXPECT_EQ(7ul, last_data_[0].size());
279   EXPECT_EQ((int)NfcStatus::OK, last_data_[0][3]);
280   uint8_t conn_id = last_data_[0][6];
281   uint32_t max_payload_size = last_data_[0][4];
282
283   for (int loops = 0; loops < NUMBER_LOOPS; loops++) {
284     last_data_.resize(0);
285     data.resize(max_payload_size + LOOP_BACK_HEADER_SIZE);
286     data[0] = conn_id;
287     data[1] = 0x00;
288     data[2] = max_payload_size;
289     for (uint32_t i = 0; i < max_payload_size; i++) {
290       data[i + LOOP_BACK_HEADER_SIZE] = i;
291     }
292     EXPECT_EQ(max_payload_size + LOOP_BACK_HEADER_SIZE, nfc_->write(data));
293     // Wait for data and CORE_CONN_CREDITS_NTF
294     EXPECT_EQ(std::cv_status::no_timeout, wait());
295     EXPECT_EQ(std::cv_status::no_timeout, wait());
296     // Check if the same data was recieved back
297     EXPECT_EQ(2ul, last_data_.size());
298
299     /* It is possible that CORE_CONN_CREDITS_NTF is received before data,
300      * Find the order and do further checks depending on that */
301     uint8_t data_index = last_data_[0].size() == data.size() ? 0 : 1;
302     EXPECT_EQ(data.size(), last_data_[data_index].size());
303     for (size_t i = 0; i < data.size(); i++) {
304       EXPECT_EQ(data[i], last_data_[data_index][i]);
305     }
306
307     EXPECT_EQ(6ul, last_data_[!data_index].size());
308     // Check if the credit is refilled to 1
309     EXPECT_EQ(1, last_data_[!data_index][5]);
310   }
311 }
312
313 /*
314  * PowerCycle:
315  * Calls powerCycle()
316  * Waits for NfcEvent.OPEN_CPLT
317  * Checks status
318  */
319 TEST_F(NfcHidlTest, PowerCycle) {
320   EXPECT_EQ(NfcStatus::OK, nfc_->powerCycle());
321   // Wait for NfcEvent.OPEN_CPLT
322   EXPECT_EQ(std::cv_status::no_timeout, wait());
323   EXPECT_EQ(NfcEvent::OPEN_CPLT, last_event_);
324   EXPECT_EQ(NfcStatus::OK, last_status_);
325 }
326
327 /*
328  * CoreInitialized:
329  * Calls coreInitialized()
330  * Waits for NfcEvent.POST_INIT_CPLT
331  */
332 TEST_F(NfcHidlTest, CoreInitialized) {
333   NfcData data;
334   data.resize(1);
335   data[0] = 0;
336   EXPECT_EQ(NfcStatus::OK, nfc_->coreInitialized(data));
337   // Wait for NfcEvent.POST_INIT_CPLT
338   EXPECT_EQ(std::cv_status::no_timeout, wait());
339   EXPECT_EQ(NfcEvent::POST_INIT_CPLT, last_event_);
340 }
341
342 /*
343  * ControlGranted:
344  * Calls controlGranted()
345  * Checks the return value
346  */
347 TEST_F(NfcHidlTest, ControlGranted) {
348   EXPECT_EQ(NfcStatus::OK, nfc_->controlGranted());
349 }
350
351 /* PreDiscover:
352  * Calls prediscover()
353  * Checks the return value
354  */
355 TEST_F(NfcHidlTest, PreDiscover) {
356   EXPECT_EQ(NfcStatus::OK, nfc_->prediscover());
357 }
358
359 int main(int argc, char** argv) {
360   ::testing::AddGlobalTestEnvironment(new NfcHidlEnvironment);
361   ::testing::InitGoogleTest(&argc, argv);
362
363   std::system("svc nfc disable"); /* Turn off NFC */
364   sleep(5);
365
366   int status = RUN_ALL_TESTS();
367   LOG(INFO) << "Test result = " << status;
368
369   std::system("svc nfc enable"); /* Turn on NFC */
370   sleep(5);
371
372   return status;
373 }