xref: /linux/tools/testing/selftests/nci/nci_dev.c (revision ff9b465ddb95d7842282998348df88ff55f62c4a)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (C) 2021 Samsung Electronics
4  * Bongsu Jeon <bongsu.jeon@samsung.com>
5  *
6  * Test code for nci
7  */
8 
9 #include <stdlib.h>
10 #include <errno.h>
11 #include <stdint.h>
12 #include <string.h>
13 #include <sys/ioctl.h>
14 #include <fcntl.h>
15 #include <pthread.h>
16 #include <linux/genetlink.h>
17 #include <sys/socket.h>
18 #include <linux/nfc.h>
19 
20 #include "kselftest_harness.h"
21 
22 #define GENLMSG_DATA(glh)	((void *)(NLMSG_DATA(glh) + GENL_HDRLEN))
23 #define GENLMSG_PAYLOAD(glh)	(NLMSG_PAYLOAD(glh, 0) - GENL_HDRLEN)
24 #define NLA_DATA(na)		((void *)((char *)(na) + NLA_HDRLEN))
25 #define NLA_PAYLOAD(len)	((len) - NLA_HDRLEN)
26 
27 #define MAX_MSG_SIZE	1024
28 
29 #define IOCTL_GET_NCIDEV_IDX	0
30 #define VIRTUAL_NFC_PROTOCOLS	(NFC_PROTO_JEWEL_MASK | \
31 				 NFC_PROTO_MIFARE_MASK | \
32 				 NFC_PROTO_FELICA_MASK | \
33 				 NFC_PROTO_ISO14443_MASK | \
34 				 NFC_PROTO_ISO14443_B_MASK | \
35 				 NFC_PROTO_ISO15693_MASK)
36 
37 const __u8 nci_reset_cmd[] = {0x20, 0x00, 0x01, 0x01};
38 const __u8 nci_init_cmd[] = {0x20, 0x01, 0x00};
39 const __u8 nci_rf_discovery_cmd[] = {0x21, 0x03, 0x09, 0x04, 0x00, 0x01,
40 				      0x01, 0x01, 0x02, 0x01, 0x06, 0x01};
41 const __u8 nci_init_cmd_v2[] = {0x20, 0x01, 0x02, 0x00, 0x00};
42 const __u8 nci_rf_disc_map_cmd[] = {0x21, 0x00, 0x07, 0x02, 0x04, 0x03,
43 				     0x02, 0x05, 0x03, 0x03};
44 const __u8 nci_rf_deact_cmd[] = {0x21, 0x06, 0x01, 0x00};
45 const __u8 nci_reset_rsp[] = {0x40, 0x00, 0x03, 0x00, 0x10, 0x01};
46 const __u8 nci_reset_rsp_v2[] = {0x40, 0x00, 0x01, 0x00};
47 const __u8 nci_reset_ntf[] = {0x60, 0x00, 0x09, 0x02, 0x01, 0x20, 0x0e,
48 			       0x04, 0x61, 0x00, 0x04, 0x02};
49 const __u8 nci_init_rsp[] = {0x40, 0x01, 0x14, 0x00, 0x02, 0x0e, 0x02,
50 			      0x00, 0x03, 0x01, 0x02, 0x03, 0x02, 0xc8,
51 			      0x00, 0xff, 0x10, 0x00, 0x0e, 0x12, 0x00,
52 			      0x00, 0x04};
53 const __u8 nci_init_rsp_v2[] = {0x40, 0x01, 0x1c, 0x00, 0x1a, 0x7e, 0x06,
54 				 0x00, 0x02, 0x92, 0x04, 0xff, 0xff, 0x01,
55 				 0x00, 0x40, 0x06, 0x00, 0x00, 0x01, 0x01,
56 				 0x00, 0x02, 0x00, 0x03, 0x01, 0x01, 0x06,
57 				 0x00, 0x80, 0x00};
58 const __u8 nci_rf_disc_map_rsp[] = {0x41, 0x00, 0x01, 0x00};
59 const __u8 nci_rf_disc_rsp[] = {0x41, 0x03, 0x01, 0x00};
60 const __u8 nci_rf_deact_rsp[] = {0x41, 0x06, 0x01, 0x00};
61 const __u8 nci_rf_deact_ntf[] = {0x61, 0x06, 0x02, 0x00, 0x00};
62 const __u8 nci_rf_activate_ntf[] = {0x61, 0x05, 0x1D, 0x01, 0x02, 0x04, 0x00,
63 				     0xFF, 0xFF, 0x0C, 0x44, 0x03, 0x07, 0x04,
64 				     0x62, 0x26, 0x11, 0x80, 0x1D, 0x80, 0x01,
65 				     0x20, 0x00, 0x00, 0x00, 0x06, 0x05, 0x75,
66 				     0x77, 0x81, 0x02, 0x80};
67 const __u8 nci_t4t_select_cmd[] = {0x00, 0x00, 0x0C, 0x00, 0xA4, 0x04, 0x00,
68 				    0x07, 0xD2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x01};
69 const __u8 nci_t4t_select_cmd2[] = {0x00, 0x00, 0x07, 0x00, 0xA4, 0x00, 0x0C, 0x02,
70 				     0xE1, 0x03};
71 const __u8 nci_t4t_select_cmd3[] = {0x00, 0x00, 0x07, 0x00, 0xA4, 0x00, 0x0C, 0x02,
72 				     0xE1, 0x04};
73 const __u8 nci_t4t_read_cmd[] = {0x00, 0x00, 0x05, 0x00, 0xB0, 0x00, 0x00, 0x0F};
74 const __u8 nci_t4t_read_rsp[] = {0x00, 0x00, 0x11, 0x00, 0x0F, 0x20, 0x00, 0x3B,
75 				  0x00, 0x34, 0x04, 0x06, 0xE1, 0x04, 0x08, 0x00,
76 				  0x00, 0x00, 0x90, 0x00};
77 const __u8 nci_t4t_read_cmd2[] = {0x00, 0x00, 0x05, 0x00, 0xB0, 0x00, 0x00, 0x02};
78 const __u8 nci_t4t_read_rsp2[] = {0x00, 0x00, 0x04, 0x00, 0x0F, 0x90, 0x00};
79 const __u8 nci_t4t_read_cmd3[] = {0x00, 0x00, 0x05, 0x00, 0xB0, 0x00, 0x02, 0x0F};
80 const __u8 nci_t4t_read_rsp3[] = {0x00, 0x00, 0x11, 0xD1, 0x01, 0x0B, 0x54, 0x02,
81 				   0x65, 0x6E, 0x4E, 0x46, 0x43, 0x20, 0x54, 0x45,
82 				   0x53, 0x54, 0x90, 0x00};
83 const __u8 nci_t4t_rsp_ok[] = {0x00, 0x00, 0x02, 0x90, 0x00};
84 
85 struct msgtemplate {
86 	struct nlmsghdr n;
87 	struct genlmsghdr g;
88 	char buf[MAX_MSG_SIZE];
89 };
90 
91 static int join_thread_status(pthread_t thread)
92 {
93 	void *thread_ret = NULL;
94 
95 	if (pthread_join(thread, &thread_ret))
96 		return -1;
97 
98 	return (int)(intptr_t)thread_ret;
99 }
100 
101 static int create_nl_socket(void)
102 {
103 	int fd;
104 	struct sockaddr_nl local;
105 
106 	fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
107 	if (fd < 0)
108 		return -1;
109 
110 	memset(&local, 0, sizeof(local));
111 	local.nl_family = AF_NETLINK;
112 
113 	if (bind(fd, (struct sockaddr *)&local, sizeof(local)) < 0)
114 		goto error;
115 
116 	return fd;
117 error:
118 	close(fd);
119 	return -1;
120 }
121 
122 static int send_cmd_mt_nla(int sd, __u16 nlmsg_type, __u32 nlmsg_pid,
123 			   __u8 genl_cmd, int nla_num, __u16 nla_type[],
124 			   void *nla_data[], int nla_len[], __u16 flags)
125 {
126 	struct sockaddr_nl nladdr;
127 	struct msgtemplate msg;
128 	struct nlattr *na;
129 	int cnt, prv_len;
130 	int r, buflen;
131 	char *buf;
132 
133 	msg.n.nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN);
134 	msg.n.nlmsg_type = nlmsg_type;
135 	msg.n.nlmsg_flags = flags;
136 	msg.n.nlmsg_seq = 0;
137 	msg.n.nlmsg_pid = nlmsg_pid;
138 	msg.g.cmd = genl_cmd;
139 	msg.g.version = 0x1;
140 
141 	prv_len = 0;
142 	for (cnt = 0; cnt < nla_num; cnt++) {
143 		na = (struct nlattr *)(GENLMSG_DATA(&msg) + prv_len);
144 		na->nla_type = nla_type[cnt];
145 		na->nla_len = nla_len[cnt] + NLA_HDRLEN;
146 
147 		if (nla_len[cnt] > 0)
148 			memcpy(NLA_DATA(na), nla_data[cnt], nla_len[cnt]);
149 
150 		prv_len = NLA_ALIGN(nla_len[cnt]) + NLA_HDRLEN;
151 		msg.n.nlmsg_len += prv_len;
152 	}
153 
154 	buf = (char *)&msg;
155 	buflen = msg.n.nlmsg_len;
156 	memset(&nladdr, 0, sizeof(nladdr));
157 	nladdr.nl_family = AF_NETLINK;
158 
159 	while ((r = sendto(sd, buf, buflen, 0, (struct sockaddr *)&nladdr,
160 			   sizeof(nladdr))) < buflen) {
161 		if (r > 0) {
162 			buf += r;
163 			buflen -= r;
164 		} else if (errno != EAGAIN) {
165 			return -1;
166 		}
167 	}
168 	return 0;
169 }
170 
171 static int send_get_nfc_family(int sd, __u32 pid)
172 {
173 	__u16 nla_get_family_type = CTRL_ATTR_FAMILY_NAME;
174 	void *nla_get_family_data;
175 	int nla_get_family_len;
176 	char family_name[100];
177 
178 	nla_get_family_len = strlen(NFC_GENL_NAME) + 1;
179 	strcpy(family_name, NFC_GENL_NAME);
180 	nla_get_family_data = family_name;
181 
182 	return send_cmd_mt_nla(sd, GENL_ID_CTRL, pid, CTRL_CMD_GETFAMILY,
183 				1, &nla_get_family_type, &nla_get_family_data,
184 				&nla_get_family_len, NLM_F_REQUEST);
185 }
186 
187 static int get_family_id(int sd, __u32 pid, __u32 *event_group)
188 {
189 	struct {
190 		struct nlmsghdr n;
191 		struct genlmsghdr g;
192 		char buf[512];
193 	} ans;
194 	struct nlattr *na;
195 	int resp_len;
196 	__u16 id = 0;
197 	int len;
198 	int rc;
199 
200 	rc = send_get_nfc_family(sd, pid);
201 
202 	if (rc < 0)
203 		return 0;
204 
205 	resp_len = recv(sd, &ans, sizeof(ans), 0);
206 
207 	if (ans.n.nlmsg_type == NLMSG_ERROR || resp_len < 0 ||
208 	    !NLMSG_OK(&ans.n, resp_len))
209 		return 0;
210 
211 	len = 0;
212 	resp_len = GENLMSG_PAYLOAD(&ans.n);
213 	na = (struct nlattr *)GENLMSG_DATA(&ans);
214 
215 	while (len < resp_len) {
216 		len += NLA_ALIGN(na->nla_len);
217 		if (na->nla_type == CTRL_ATTR_FAMILY_ID) {
218 			id = *(__u16 *)NLA_DATA(na);
219 		} else if (na->nla_type == CTRL_ATTR_MCAST_GROUPS) {
220 			struct nlattr *nested_na;
221 			struct nlattr *group_na;
222 			int group_attr_len;
223 			int group_attr;
224 
225 			nested_na = (struct nlattr *)((char *)na + NLA_HDRLEN);
226 			group_na = (struct nlattr *)((char *)nested_na + NLA_HDRLEN);
227 			group_attr_len = 0;
228 
229 			for (group_attr = CTRL_ATTR_MCAST_GRP_UNSPEC;
230 				group_attr < CTRL_ATTR_MCAST_GRP_MAX; group_attr++) {
231 				if (group_na->nla_type == CTRL_ATTR_MCAST_GRP_ID) {
232 					*event_group = *(__u32 *)((char *)group_na +
233 								  NLA_HDRLEN);
234 					break;
235 				}
236 
237 				group_attr_len += NLA_ALIGN(group_na->nla_len) +
238 						  NLA_HDRLEN;
239 				if (group_attr_len >= nested_na->nla_len)
240 					break;
241 
242 				group_na = (struct nlattr *)((char *)group_na +
243 							     NLA_ALIGN(group_na->nla_len));
244 			}
245 		}
246 		na = (struct nlattr *)(GENLMSG_DATA(&ans) + len);
247 	}
248 	return id;
249 }
250 
251 static int send_cmd_with_idx(int sd, __u16 nlmsg_type, __u32 nlmsg_pid,
252 			     __u8 genl_cmd, int dev_id)
253 {
254 	__u16 nla_type = NFC_ATTR_DEVICE_INDEX;
255 	void *nla_data = &dev_id;
256 	int nla_len = 4;
257 
258 	return send_cmd_mt_nla(sd, nlmsg_type, nlmsg_pid, genl_cmd, 1,
259 				&nla_type, &nla_data, &nla_len, NLM_F_REQUEST);
260 }
261 
262 static int get_nci_devid(int sd, __u16 fid, __u32 pid, int dev_id, struct msgtemplate *msg)
263 {
264 	int rc, resp_len;
265 
266 	rc = send_cmd_with_idx(sd, fid, pid, NFC_CMD_GET_DEVICE, dev_id);
267 	if (rc < 0) {
268 		rc = -1;
269 		goto error;
270 	}
271 
272 	resp_len = recv(sd, msg, sizeof(*msg), 0);
273 	if (resp_len < 0) {
274 		rc = -2;
275 		goto error;
276 	}
277 
278 	if (msg->n.nlmsg_type == NLMSG_ERROR ||
279 	    !NLMSG_OK(&msg->n, resp_len)) {
280 		rc = -3;
281 		goto error;
282 	}
283 
284 	return 0;
285 error:
286 	return rc;
287 }
288 
289 static __u8 get_dev_enable_state(struct msgtemplate *msg)
290 {
291 	struct nlattr *na;
292 	int resp_len;
293 	int len;
294 
295 	resp_len = GENLMSG_PAYLOAD(&msg->n);
296 	na = (struct nlattr *)GENLMSG_DATA(msg);
297 	len = 0;
298 
299 	while (len < resp_len) {
300 		len += NLA_ALIGN(na->nla_len);
301 		if (na->nla_type == NFC_ATTR_DEVICE_POWERED)
302 			return *(char *)NLA_DATA(na);
303 		na = (struct nlattr *)(GENLMSG_DATA(msg) + len);
304 	}
305 
306 	return resp_len;
307 }
308 
309 FIXTURE(NCI) {
310 	int virtual_nci_fd;
311 	bool open_state;
312 	int dev_idex;
313 	bool isNCI2;
314 	int proto;
315 	__u32 pid;
316 	__u16 fid;
317 	int sd;
318 };
319 
320 FIXTURE_VARIANT(NCI) {
321 	bool isNCI2;
322 };
323 
324 FIXTURE_VARIANT_ADD(NCI, NCI1_0) {
325 	.isNCI2 = false,
326 };
327 
328 FIXTURE_VARIANT_ADD(NCI, NCI2_0) {
329 	.isNCI2 = true,
330 };
331 
332 static void *virtual_dev_open(void *data)
333 {
334 	char buf[258];
335 	int dev_fd;
336 	int len;
337 
338 	dev_fd = *(int *)data;
339 
340 	len = read(dev_fd, buf, 258);
341 	if (len <= 0)
342 		goto error;
343 	if (len != sizeof(nci_reset_cmd))
344 		goto error;
345 	if (memcmp(nci_reset_cmd, buf, len))
346 		goto error;
347 	write(dev_fd, nci_reset_rsp, sizeof(nci_reset_rsp));
348 
349 	len = read(dev_fd, buf, 258);
350 	if (len <= 0)
351 		goto error;
352 	if (len != sizeof(nci_init_cmd))
353 		goto error;
354 	if (memcmp(nci_init_cmd, buf, len))
355 		goto error;
356 	write(dev_fd, nci_init_rsp, sizeof(nci_init_rsp));
357 
358 	len = read(dev_fd, buf, 258);
359 	if (len <= 0)
360 		goto error;
361 	if (len != sizeof(nci_rf_disc_map_cmd))
362 		goto error;
363 	if (memcmp(nci_rf_disc_map_cmd, buf, len))
364 		goto error;
365 	write(dev_fd, nci_rf_disc_map_rsp, sizeof(nci_rf_disc_map_rsp));
366 
367 	return (void *)0;
368 error:
369 	return (void *)-1;
370 }
371 
372 static void *virtual_dev_open_v2(void *data)
373 {
374 	char buf[258];
375 	int dev_fd;
376 	int len;
377 
378 	dev_fd = *(int *)data;
379 
380 	len = read(dev_fd, buf, 258);
381 	if (len <= 0)
382 		goto error;
383 	if (len != sizeof(nci_reset_cmd))
384 		goto error;
385 	if (memcmp(nci_reset_cmd, buf, len))
386 		goto error;
387 	write(dev_fd, nci_reset_rsp_v2, sizeof(nci_reset_rsp_v2));
388 	write(dev_fd, nci_reset_ntf, sizeof(nci_reset_ntf));
389 
390 	len = read(dev_fd, buf, 258);
391 	if (len <= 0)
392 		goto error;
393 	if (len != sizeof(nci_init_cmd_v2))
394 		goto error;
395 	if (memcmp(nci_init_cmd_v2, buf, len))
396 		goto error;
397 	write(dev_fd, nci_init_rsp_v2, sizeof(nci_init_rsp_v2));
398 
399 	len = read(dev_fd, buf, 258);
400 	if (len <= 0)
401 		goto error;
402 	if (len != sizeof(nci_rf_disc_map_cmd))
403 		goto error;
404 	if (memcmp(nci_rf_disc_map_cmd, buf, len))
405 		goto error;
406 	write(dev_fd, nci_rf_disc_map_rsp, sizeof(nci_rf_disc_map_rsp));
407 
408 	return (void *)0;
409 error:
410 	return (void *)-1;
411 }
412 
413 FIXTURE_SETUP(NCI)
414 {
415 	struct msgtemplate msg;
416 	pthread_t thread_t;
417 	__u32 event_group;
418 	int status;
419 	int rc;
420 
421 	self->open_state = false;
422 	self->proto = VIRTUAL_NFC_PROTOCOLS;
423 	self->isNCI2 = variant->isNCI2;
424 
425 	self->sd = create_nl_socket();
426 	ASSERT_NE(self->sd, -1);
427 
428 	self->pid = getpid();
429 	self->fid = get_family_id(self->sd, self->pid, &event_group);
430 	ASSERT_NE(self->fid, -1);
431 
432 	self->virtual_nci_fd = open("/dev/virtual_nci", O_RDWR);
433 	ASSERT_GT(self->virtual_nci_fd, -1);
434 
435 	rc = setsockopt(self->sd, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, &event_group,
436 			sizeof(event_group));
437 	ASSERT_NE(rc, -1);
438 
439 	rc = ioctl(self->virtual_nci_fd, IOCTL_GET_NCIDEV_IDX, &self->dev_idex);
440 	ASSERT_EQ(rc, 0);
441 
442 	rc = get_nci_devid(self->sd, self->fid, self->pid, self->dev_idex, &msg);
443 	ASSERT_EQ(rc, 0);
444 	EXPECT_EQ(get_dev_enable_state(&msg), 0);
445 
446 	if (self->isNCI2)
447 		rc = pthread_create(&thread_t, NULL, virtual_dev_open_v2,
448 				    (void *)&self->virtual_nci_fd);
449 	else
450 		rc = pthread_create(&thread_t, NULL, virtual_dev_open,
451 				    (void *)&self->virtual_nci_fd);
452 	ASSERT_EQ(rc, 0);
453 
454 	rc = send_cmd_with_idx(self->sd, self->fid, self->pid,
455 			       NFC_CMD_DEV_UP, self->dev_idex);
456 	EXPECT_EQ(rc, 0);
457 
458 	status = join_thread_status(thread_t);
459 	ASSERT_EQ(status, 0);
460 	self->open_state = true;
461 }
462 
463 static void *virtual_deinit(void *data)
464 {
465 	char buf[258];
466 	int dev_fd;
467 	int len;
468 
469 	dev_fd = *(int *)data;
470 
471 	len = read(dev_fd, buf, 258);
472 	if (len <= 0)
473 		goto error;
474 	if (len != sizeof(nci_reset_cmd))
475 		goto error;
476 	if (memcmp(nci_reset_cmd, buf, len))
477 		goto error;
478 	write(dev_fd, nci_reset_rsp, sizeof(nci_reset_rsp));
479 
480 	return (void *)0;
481 error:
482 	return (void *)-1;
483 }
484 
485 static void *virtual_deinit_v2(void *data)
486 {
487 	char buf[258];
488 	int dev_fd;
489 	int len;
490 
491 	dev_fd = *(int *)data;
492 
493 	len = read(dev_fd, buf, 258);
494 	if (len <= 0)
495 		goto error;
496 	if (len != sizeof(nci_reset_cmd))
497 		goto error;
498 	if (memcmp(nci_reset_cmd, buf, len))
499 		goto error;
500 	write(dev_fd, nci_reset_rsp_v2, sizeof(nci_reset_rsp_v2));
501 	write(dev_fd, nci_reset_ntf, sizeof(nci_reset_ntf));
502 
503 	return (void *)0;
504 error:
505 	return (void *)-1;
506 }
507 
508 FIXTURE_TEARDOWN(NCI)
509 {
510 	pthread_t thread_t;
511 	int status;
512 	int rc;
513 
514 	if (self->open_state) {
515 		if (self->isNCI2)
516 			rc = pthread_create(&thread_t, NULL,
517 					    virtual_deinit_v2,
518 					    (void *)&self->virtual_nci_fd);
519 		else
520 			rc = pthread_create(&thread_t, NULL, virtual_deinit,
521 					    (void *)&self->virtual_nci_fd);
522 
523 		ASSERT_EQ(rc, 0);
524 		rc = send_cmd_with_idx(self->sd, self->fid, self->pid,
525 				       NFC_CMD_DEV_DOWN, self->dev_idex);
526 		EXPECT_EQ(rc, 0);
527 
528 		status = join_thread_status(thread_t);
529 		ASSERT_EQ(status, 0);
530 	}
531 
532 	close(self->sd);
533 	close(self->virtual_nci_fd);
534 	self->open_state = false;
535 }
536 
537 TEST_F(NCI, init)
538 {
539 	struct msgtemplate msg;
540 	int rc;
541 
542 	rc = get_nci_devid(self->sd, self->fid, self->pid, self->dev_idex,
543 			   &msg);
544 	ASSERT_EQ(rc, 0);
545 	EXPECT_EQ(get_dev_enable_state(&msg), 1);
546 }
547 
548 static void *virtual_poll_start(void *data)
549 {
550 	char buf[258];
551 	int dev_fd;
552 	int len;
553 
554 	dev_fd = *(int *)data;
555 
556 	len = read(dev_fd, buf, 258);
557 	if (len <= 0)
558 		goto error;
559 	if (len != sizeof(nci_rf_discovery_cmd))
560 		goto error;
561 	if (memcmp(nci_rf_discovery_cmd, buf, len))
562 		goto error;
563 	write(dev_fd, nci_rf_disc_rsp, sizeof(nci_rf_disc_rsp));
564 
565 	return (void *)0;
566 error:
567 	return (void *)-1;
568 }
569 
570 static void *virtual_poll_stop(void *data)
571 {
572 	char buf[258];
573 	int dev_fd;
574 	int len;
575 
576 	dev_fd = *(int *)data;
577 
578 	len = read(dev_fd, buf, 258);
579 	if (len <= 0)
580 		goto error;
581 	if (len != sizeof(nci_rf_deact_cmd))
582 		goto error;
583 	if (memcmp(nci_rf_deact_cmd, buf, len))
584 		goto error;
585 	write(dev_fd, nci_rf_deact_rsp, sizeof(nci_rf_deact_rsp));
586 
587 	return (void *)0;
588 error:
589 	return (void *)-1;
590 }
591 
592 int start_polling(int dev_idx, int proto, int virtual_fd, int sd, int fid, int pid)
593 {
594 	__u16 nla_start_poll_type[2] = {NFC_ATTR_DEVICE_INDEX,
595 					 NFC_ATTR_PROTOCOLS};
596 	void *nla_start_poll_data[2] = {&dev_idx, &proto};
597 	int nla_start_poll_len[2] = {4, 4};
598 	pthread_t thread_t;
599 	int rc;
600 
601 	rc = pthread_create(&thread_t, NULL, virtual_poll_start,
602 			    (void *)&virtual_fd);
603 	if (rc)
604 		return rc;
605 
606 	rc = send_cmd_mt_nla(sd, fid, pid, NFC_CMD_START_POLL, 2, nla_start_poll_type,
607 			     nla_start_poll_data, nla_start_poll_len, NLM_F_REQUEST);
608 	if (rc != 0)
609 		return rc;
610 
611 	return join_thread_status(thread_t);
612 }
613 
614 int stop_polling(int dev_idx, int virtual_fd, int sd, int fid, int pid)
615 {
616 	pthread_t thread_t;
617 	int rc;
618 
619 	rc = pthread_create(&thread_t, NULL, virtual_poll_stop,
620 			    (void *)&virtual_fd);
621 	if (rc)
622 		return rc;
623 
624 	rc = send_cmd_with_idx(sd, fid, pid,
625 			       NFC_CMD_STOP_POLL, dev_idx);
626 	if (rc != 0)
627 		return rc;
628 
629 	return join_thread_status(thread_t);
630 }
631 
632 TEST_F(NCI, start_poll)
633 {
634 	int status;
635 
636 	status = start_polling(self->dev_idex, self->proto, self->virtual_nci_fd,
637 			       self->sd, self->fid, self->pid);
638 	EXPECT_EQ(status, 0);
639 
640 	status = stop_polling(self->dev_idex, self->virtual_nci_fd, self->sd,
641 			      self->fid, self->pid);
642 	EXPECT_EQ(status, 0);
643 }
644 
645 int get_taginfo(int dev_idx, int sd, int fid, int pid)
646 {
647 	struct {
648 		struct nlmsghdr n;
649 		struct genlmsghdr g;
650 		char buf[512];
651 	} ans;
652 
653 	struct nlattr *na;
654 	__u32 protocol;
655 	int targetidx;
656 	__u8 sel_res;
657 	int resp_len;
658 	int len;
659 
660 	__u16 tagid_type;
661 	void *tagid_type_data;
662 	int tagid_len;
663 
664 	tagid_type = NFC_ATTR_DEVICE_INDEX;
665 	tagid_type_data = &dev_idx;
666 	tagid_len = 4;
667 
668 	send_cmd_mt_nla(sd, fid, pid, NFC_CMD_GET_TARGET, 1, &tagid_type,
669 			&tagid_type_data, &tagid_len, NLM_F_REQUEST | NLM_F_DUMP);
670 	resp_len = recv(sd, &ans, sizeof(ans), 0);
671 	if (ans.n.nlmsg_type == NLMSG_ERROR || resp_len < 0 ||
672 	    !NLMSG_OK(&ans.n, resp_len))
673 		return -1;
674 
675 	resp_len = GENLMSG_PAYLOAD(&ans.n);
676 	na = (struct nlattr *)GENLMSG_DATA(&ans);
677 
678 	len = 0;
679 	targetidx = -1;
680 	protocol = -1;
681 	sel_res = -1;
682 
683 	while (len < resp_len) {
684 		len += NLA_ALIGN(na->nla_len);
685 
686 		if (na->nla_type == NFC_ATTR_TARGET_INDEX)
687 			targetidx = *(int *)((char *)na + NLA_HDRLEN);
688 		else if (na->nla_type == NFC_ATTR_TARGET_SEL_RES)
689 			sel_res = *(__u8 *)((char *)na + NLA_HDRLEN);
690 		else if (na->nla_type == NFC_ATTR_PROTOCOLS)
691 			protocol = *(__u32 *)((char *)na + NLA_HDRLEN);
692 
693 		na = (struct nlattr *)(GENLMSG_DATA(&ans) + len);
694 	}
695 
696 	if (targetidx == -1 || sel_res != 0x20 || protocol != NFC_PROTO_ISO14443_MASK)
697 		return -1;
698 
699 	return targetidx;
700 }
701 
702 int connect_socket(int dev_idx, int target_idx)
703 {
704 	struct sockaddr_nfc addr;
705 	int sock;
706 	int err = 0;
707 
708 	sock = socket(AF_NFC, SOCK_SEQPACKET, NFC_SOCKPROTO_RAW);
709 	if (sock == -1)
710 		return -1;
711 
712 	addr.sa_family = AF_NFC;
713 	addr.dev_idx = dev_idx;
714 	addr.target_idx = target_idx;
715 	addr.nfc_protocol = NFC_PROTO_ISO14443;
716 
717 	err = connect(sock, (struct sockaddr *)&addr, sizeof(addr));
718 	if (err) {
719 		close(sock);
720 		return -1;
721 	}
722 
723 	return sock;
724 }
725 
726 int connect_tag(int dev_idx, int virtual_fd, int sd, int fid, int pid)
727 {
728 	struct genlmsghdr *genlhdr;
729 	struct nlattr *na;
730 	char evt_data[255];
731 	int target_idx;
732 	int resp_len;
733 	int evt_dev;
734 
735 	write(virtual_fd, nci_rf_activate_ntf, sizeof(nci_rf_activate_ntf));
736 	resp_len = recv(sd, evt_data, sizeof(evt_data), 0);
737 	if (resp_len < 0)
738 		return -1;
739 
740 	genlhdr = (struct genlmsghdr *)((struct nlmsghdr *)evt_data + 1);
741 	na = (struct nlattr *)(genlhdr + 1);
742 	evt_dev = *(int *)((char *)na + NLA_HDRLEN);
743 	if (dev_idx != evt_dev)
744 		return -1;
745 
746 	target_idx = get_taginfo(dev_idx, sd, fid, pid);
747 	if (target_idx == -1)
748 		return -1;
749 	return connect_socket(dev_idx, target_idx);
750 }
751 
752 int read_write_nci_cmd(int nfc_sock, int virtual_fd, const __u8 *cmd, __u32 cmd_len,
753 		       const __u8 *rsp, __u32 rsp_len)
754 {
755 	char buf[256];
756 	int len;
757 
758 	send(nfc_sock, &cmd[3], cmd_len - 3, 0);
759 	len = read(virtual_fd, buf, cmd_len);
760 	if (len < 0 || memcmp(buf, cmd, cmd_len))
761 		return -1;
762 
763 	write(virtual_fd, rsp, rsp_len);
764 	len = recv(nfc_sock, buf, rsp_len - 2, 0);
765 	if (len < 0 || memcmp(&buf[1], &rsp[3], rsp_len - 3))
766 		return -1;
767 
768 	return 0;
769 }
770 
771 int read_tag(int nfc_sock, int virtual_fd)
772 {
773 	if (read_write_nci_cmd(nfc_sock, virtual_fd, nci_t4t_select_cmd,
774 			       sizeof(nci_t4t_select_cmd), nci_t4t_rsp_ok,
775 			       sizeof(nci_t4t_rsp_ok)))
776 		return -1;
777 
778 	if (read_write_nci_cmd(nfc_sock, virtual_fd, nci_t4t_select_cmd2,
779 			       sizeof(nci_t4t_select_cmd2), nci_t4t_rsp_ok,
780 			       sizeof(nci_t4t_rsp_ok)))
781 		return -1;
782 
783 	if (read_write_nci_cmd(nfc_sock, virtual_fd, nci_t4t_read_cmd,
784 			       sizeof(nci_t4t_read_cmd), nci_t4t_read_rsp,
785 			       sizeof(nci_t4t_read_rsp)))
786 		return -1;
787 
788 	if (read_write_nci_cmd(nfc_sock, virtual_fd, nci_t4t_select_cmd3,
789 			       sizeof(nci_t4t_select_cmd3), nci_t4t_rsp_ok,
790 			       sizeof(nci_t4t_rsp_ok)))
791 		return -1;
792 
793 	if (read_write_nci_cmd(nfc_sock, virtual_fd, nci_t4t_read_cmd2,
794 			       sizeof(nci_t4t_read_cmd2), nci_t4t_read_rsp2,
795 			       sizeof(nci_t4t_read_rsp2)))
796 		return -1;
797 
798 	return read_write_nci_cmd(nfc_sock, virtual_fd, nci_t4t_read_cmd3,
799 				  sizeof(nci_t4t_read_cmd3), nci_t4t_read_rsp3,
800 				  sizeof(nci_t4t_read_rsp3));
801 }
802 
803 static void *virtual_deactivate_proc(void *data)
804 {
805 	int virtual_fd;
806 	char buf[256];
807 	int deactcmd_len;
808 	int len;
809 
810 	virtual_fd = *(int *)data;
811 	deactcmd_len = sizeof(nci_rf_deact_cmd);
812 	len = read(virtual_fd, buf, deactcmd_len);
813 	if (len != deactcmd_len || memcmp(buf, nci_rf_deact_cmd, deactcmd_len))
814 		return (void *)-1;
815 
816 	write(virtual_fd, nci_rf_deact_rsp, sizeof(nci_rf_deact_rsp));
817 	write(virtual_fd, nci_rf_deact_ntf, sizeof(nci_rf_deact_ntf));
818 
819 	return (void *)0;
820 }
821 
822 int disconnect_tag(int nfc_sock, int virtual_fd)
823 {
824 	pthread_t thread_t;
825 	char buf[256];
826 	int status;
827 	int len;
828 
829 	send(nfc_sock, &nci_t4t_select_cmd3[3], sizeof(nci_t4t_select_cmd3) - 3, 0);
830 	len = read(virtual_fd, buf, sizeof(nci_t4t_select_cmd3));
831 	if (len < 0 || memcmp(buf, nci_t4t_select_cmd3, sizeof(nci_t4t_select_cmd3)))
832 		return -1;
833 
834 	len = recv(nfc_sock, buf, sizeof(nci_t4t_rsp_ok), 0);
835 	if (len != -1)
836 		return -1;
837 
838 	status = pthread_create(&thread_t, NULL, virtual_deactivate_proc,
839 				(void *)&virtual_fd);
840 	if (status)
841 		return status;
842 
843 	close(nfc_sock);
844 	if (status)
845 		return -1;
846 
847 	return join_thread_status(thread_t);
848 }
849 
850 TEST_F(NCI, t4t_tag_read)
851 {
852 	int nfc_sock;
853 	int status;
854 
855 	status = start_polling(self->dev_idex, self->proto, self->virtual_nci_fd,
856 			       self->sd, self->fid, self->pid);
857 	EXPECT_EQ(status, 0);
858 
859 	nfc_sock = connect_tag(self->dev_idex, self->virtual_nci_fd, self->sd,
860 			       self->fid, self->pid);
861 	ASSERT_GT(nfc_sock, -1);
862 
863 	status = read_tag(nfc_sock, self->virtual_nci_fd);
864 	ASSERT_EQ(status, 0);
865 
866 	status = disconnect_tag(nfc_sock, self->virtual_nci_fd);
867 	EXPECT_EQ(status, 0);
868 }
869 
870 TEST_F(NCI, deinit)
871 {
872 	struct msgtemplate msg;
873 	pthread_t thread_t;
874 	int status;
875 	int rc;
876 
877 	rc = get_nci_devid(self->sd, self->fid, self->pid, self->dev_idex,
878 			   &msg);
879 	ASSERT_EQ(rc, 0);
880 	EXPECT_EQ(get_dev_enable_state(&msg), 1);
881 
882 	if (self->isNCI2)
883 		rc = pthread_create(&thread_t, NULL, virtual_deinit_v2,
884 				    (void *)&self->virtual_nci_fd);
885 	else
886 		rc = pthread_create(&thread_t, NULL, virtual_deinit,
887 				    (void *)&self->virtual_nci_fd);
888 	ASSERT_EQ(rc, 0);
889 
890 	rc = send_cmd_with_idx(self->sd, self->fid, self->pid,
891 			       NFC_CMD_DEV_DOWN, self->dev_idex);
892 	EXPECT_EQ(rc, 0);
893 
894 	status = join_thread_status(thread_t);
895 	self->open_state = 0;
896 	ASSERT_EQ(status, 0);
897 
898 	rc = get_nci_devid(self->sd, self->fid, self->pid, self->dev_idex,
899 			   &msg);
900 	ASSERT_EQ(rc, 0);
901 	EXPECT_EQ(get_dev_enable_state(&msg), 0);
902 
903 	/* Test that operations that normally send packets to the driver
904 	 * don't cause issues when the device is already closed.
905 	 * Note: the send of NFC_CMD_DEV_UP itself still succeeds it's just
906 	 * that the device won't actually be up.
907 	 */
908 	close(self->virtual_nci_fd);
909 	self->virtual_nci_fd = -1;
910 	rc = send_cmd_with_idx(self->sd, self->fid, self->pid,
911 			       NFC_CMD_DEV_UP, self->dev_idex);
912 	EXPECT_EQ(rc, 0);
913 }
914 
915 TEST_HARNESS_MAIN
916