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