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
join_thread_status(pthread_t thread)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
create_nl_socket(void)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
send_cmd_mt_nla(int sd,__u16 nlmsg_type,__u32 nlmsg_pid,__u8 genl_cmd,int nla_num,__u16 nla_type[],void * nla_data[],int nla_len[],__u16 flags)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
send_get_nfc_family(int sd,__u32 pid)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
get_family_id(int sd,__u32 pid,__u32 * event_group)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
send_cmd_with_idx(int sd,__u16 nlmsg_type,__u32 nlmsg_pid,__u8 genl_cmd,int dev_id)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
get_nci_devid(int sd,__u16 fid,__u32 pid,int dev_id,struct msgtemplate * msg)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
get_dev_enable_state(struct msgtemplate * msg)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
FIXTURE(NCI)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
FIXTURE_VARIANT(NCI)320 FIXTURE_VARIANT(NCI) {
321 bool isNCI2;
322 };
323
FIXTURE_VARIANT_ADD(NCI,NCI1_0)324 FIXTURE_VARIANT_ADD(NCI, NCI1_0) {
325 .isNCI2 = false,
326 };
327
FIXTURE_VARIANT_ADD(NCI,NCI2_0)328 FIXTURE_VARIANT_ADD(NCI, NCI2_0) {
329 .isNCI2 = true,
330 };
331
virtual_dev_open(void * data)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
virtual_dev_open_v2(void * data)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
FIXTURE_SETUP(NCI)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
virtual_deinit(void * data)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
virtual_deinit_v2(void * data)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
FIXTURE_TEARDOWN(NCI)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
TEST_F(NCI,init)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
virtual_poll_start(void * data)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
virtual_poll_stop(void * data)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
start_polling(int dev_idx,int proto,int virtual_fd,int sd,int fid,int pid)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
stop_polling(int dev_idx,int virtual_fd,int sd,int fid,int pid)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
TEST_F(NCI,start_poll)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
get_taginfo(int dev_idx,int sd,int fid,int pid)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
connect_socket(int dev_idx,int target_idx)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
connect_tag(int dev_idx,int virtual_fd,int sd,int fid,int pid)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
read_write_nci_cmd(int nfc_sock,int virtual_fd,const __u8 * cmd,__u32 cmd_len,const __u8 * rsp,__u32 rsp_len)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
read_tag(int nfc_sock,int virtual_fd)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
virtual_deactivate_proc(void * data)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
disconnect_tag(int nfc_sock,int virtual_fd)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
TEST_F(NCI,t4t_tag_read)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
TEST_F(NCI,deinit)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