Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (C) 2021 Samsung Electrnoics
0004  * Bongsu Jeon <bongsu.jeon@samsung.com>
0005  *
0006  * Test code for nci
0007  */
0008 
0009 #include <stdlib.h>
0010 #include <errno.h>
0011 #include <string.h>
0012 #include <sys/ioctl.h>
0013 #include <fcntl.h>
0014 #include <pthread.h>
0015 #include <linux/genetlink.h>
0016 #include <sys/socket.h>
0017 #include <linux/nfc.h>
0018 
0019 #include "../kselftest_harness.h"
0020 
0021 #define GENLMSG_DATA(glh)   ((void *)(NLMSG_DATA(glh) + GENL_HDRLEN))
0022 #define GENLMSG_PAYLOAD(glh)    (NLMSG_PAYLOAD(glh, 0) - GENL_HDRLEN)
0023 #define NLA_DATA(na)        ((void *)((char *)(na) + NLA_HDRLEN))
0024 #define NLA_PAYLOAD(len)    ((len) - NLA_HDRLEN)
0025 
0026 #define MAX_MSG_SIZE    1024
0027 
0028 #define IOCTL_GET_NCIDEV_IDX    0
0029 #define VIRTUAL_NFC_PROTOCOLS   (NFC_PROTO_JEWEL_MASK | \
0030                  NFC_PROTO_MIFARE_MASK | \
0031                  NFC_PROTO_FELICA_MASK | \
0032                  NFC_PROTO_ISO14443_MASK | \
0033                  NFC_PROTO_ISO14443_B_MASK | \
0034                  NFC_PROTO_ISO15693_MASK)
0035 
0036 const __u8 nci_reset_cmd[] = {0x20, 0x00, 0x01, 0x01};
0037 const __u8 nci_init_cmd[] = {0x20, 0x01, 0x00};
0038 const __u8 nci_rf_discovery_cmd[] = {0x21, 0x03, 0x09, 0x04, 0x00, 0x01,
0039                       0x01, 0x01, 0x02, 0x01, 0x06, 0x01};
0040 const __u8 nci_init_cmd_v2[] = {0x20, 0x01, 0x02, 0x00, 0x00};
0041 const __u8 nci_rf_disc_map_cmd[] = {0x21, 0x00, 0x07, 0x02, 0x04, 0x03,
0042                      0x02, 0x05, 0x03, 0x03};
0043 const __u8 nci_rf_deact_cmd[] = {0x21, 0x06, 0x01, 0x00};
0044 const __u8 nci_reset_rsp[] = {0x40, 0x00, 0x03, 0x00, 0x10, 0x01};
0045 const __u8 nci_reset_rsp_v2[] = {0x40, 0x00, 0x01, 0x00};
0046 const __u8 nci_reset_ntf[] = {0x60, 0x00, 0x09, 0x02, 0x01, 0x20, 0x0e,
0047                    0x04, 0x61, 0x00, 0x04, 0x02};
0048 const __u8 nci_init_rsp[] = {0x40, 0x01, 0x14, 0x00, 0x02, 0x0e, 0x02,
0049                   0x00, 0x03, 0x01, 0x02, 0x03, 0x02, 0xc8,
0050                   0x00, 0xff, 0x10, 0x00, 0x0e, 0x12, 0x00,
0051                   0x00, 0x04};
0052 const __u8 nci_init_rsp_v2[] = {0x40, 0x01, 0x1c, 0x00, 0x1a, 0x7e, 0x06,
0053                  0x00, 0x02, 0x92, 0x04, 0xff, 0xff, 0x01,
0054                  0x00, 0x40, 0x06, 0x00, 0x00, 0x01, 0x01,
0055                  0x00, 0x02, 0x00, 0x03, 0x01, 0x01, 0x06,
0056                  0x00, 0x80, 0x00};
0057 const __u8 nci_rf_disc_map_rsp[] = {0x41, 0x00, 0x01, 0x00};
0058 const __u8 nci_rf_disc_rsp[] = {0x41, 0x03, 0x01, 0x00};
0059 const __u8 nci_rf_deact_rsp[] = {0x41, 0x06, 0x01, 0x00};
0060 const __u8 nci_rf_deact_ntf[] = {0x61, 0x06, 0x02, 0x00, 0x00};
0061 const __u8 nci_rf_activate_ntf[] = {0x61, 0x05, 0x1D, 0x01, 0x02, 0x04, 0x00,
0062                      0xFF, 0xFF, 0x0C, 0x44, 0x03, 0x07, 0x04,
0063                      0x62, 0x26, 0x11, 0x80, 0x1D, 0x80, 0x01,
0064                      0x20, 0x00, 0x00, 0x00, 0x06, 0x05, 0x75,
0065                      0x77, 0x81, 0x02, 0x80};
0066 const __u8 nci_t4t_select_cmd[] = {0x00, 0x00, 0x0C, 0x00, 0xA4, 0x04, 0x00,
0067                     0x07, 0xD2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x01};
0068 const __u8 nci_t4t_select_cmd2[] = {0x00, 0x00, 0x07, 0x00, 0xA4, 0x00, 0x0C, 0x02,
0069                      0xE1, 0x03};
0070 const __u8 nci_t4t_select_cmd3[] = {0x00, 0x00, 0x07, 0x00, 0xA4, 0x00, 0x0C, 0x02,
0071                      0xE1, 0x04};
0072 const __u8 nci_t4t_read_cmd[] = {0x00, 0x00, 0x05, 0x00, 0xB0, 0x00, 0x00, 0x0F};
0073 const __u8 nci_t4t_read_rsp[] = {0x00, 0x00, 0x11, 0x00, 0x0F, 0x20, 0x00, 0x3B,
0074                   0x00, 0x34, 0x04, 0x06, 0xE1, 0x04, 0x08, 0x00,
0075                   0x00, 0x00, 0x90, 0x00};
0076 const __u8 nci_t4t_read_cmd2[] = {0x00, 0x00, 0x05, 0x00, 0xB0, 0x00, 0x00, 0x02};
0077 const __u8 nci_t4t_read_rsp2[] = {0x00, 0x00, 0x04, 0x00, 0x0F, 0x90, 0x00};
0078 const __u8 nci_t4t_read_cmd3[] = {0x00, 0x00, 0x05, 0x00, 0xB0, 0x00, 0x02, 0x0F};
0079 const __u8 nci_t4t_read_rsp3[] = {0x00, 0x00, 0x11, 0xD1, 0x01, 0x0B, 0x54, 0x02,
0080                    0x65, 0x6E, 0x4E, 0x46, 0x43, 0x20, 0x54, 0x45,
0081                    0x53, 0x54, 0x90, 0x00};
0082 const __u8 nci_t4t_rsp_ok[] = {0x00, 0x00, 0x02, 0x90, 0x00};
0083 
0084 struct msgtemplate {
0085     struct nlmsghdr n;
0086     struct genlmsghdr g;
0087     char buf[MAX_MSG_SIZE];
0088 };
0089 
0090 static int create_nl_socket(void)
0091 {
0092     int fd;
0093     struct sockaddr_nl local;
0094 
0095     fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
0096     if (fd < 0)
0097         return -1;
0098 
0099     memset(&local, 0, sizeof(local));
0100     local.nl_family = AF_NETLINK;
0101 
0102     if (bind(fd, (struct sockaddr *)&local, sizeof(local)) < 0)
0103         goto error;
0104 
0105     return fd;
0106 error:
0107     close(fd);
0108     return -1;
0109 }
0110 
0111 static int send_cmd_mt_nla(int sd, __u16 nlmsg_type, __u32 nlmsg_pid,
0112                __u8 genl_cmd, int nla_num, __u16 nla_type[],
0113                void *nla_data[], int nla_len[], __u16 flags)
0114 {
0115     struct sockaddr_nl nladdr;
0116     struct msgtemplate msg;
0117     struct nlattr *na;
0118     int cnt, prv_len;
0119     int r, buflen;
0120     char *buf;
0121 
0122     msg.n.nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN);
0123     msg.n.nlmsg_type = nlmsg_type;
0124     msg.n.nlmsg_flags = flags;
0125     msg.n.nlmsg_seq = 0;
0126     msg.n.nlmsg_pid = nlmsg_pid;
0127     msg.g.cmd = genl_cmd;
0128     msg.g.version = 0x1;
0129 
0130     prv_len = 0;
0131     for (cnt = 0; cnt < nla_num; cnt++) {
0132         na = (struct nlattr *)(GENLMSG_DATA(&msg) + prv_len);
0133         na->nla_type = nla_type[cnt];
0134         na->nla_len = nla_len[cnt] + NLA_HDRLEN;
0135 
0136         if (nla_len[cnt] > 0)
0137             memcpy(NLA_DATA(na), nla_data[cnt], nla_len[cnt]);
0138 
0139         prv_len = NLA_ALIGN(nla_len[cnt]) + NLA_HDRLEN;
0140         msg.n.nlmsg_len += prv_len;
0141     }
0142 
0143     buf = (char *)&msg;
0144     buflen = msg.n.nlmsg_len;
0145     memset(&nladdr, 0, sizeof(nladdr));
0146     nladdr.nl_family = AF_NETLINK;
0147 
0148     while ((r = sendto(sd, buf, buflen, 0, (struct sockaddr *)&nladdr,
0149                sizeof(nladdr))) < buflen) {
0150         if (r > 0) {
0151             buf += r;
0152             buflen -= r;
0153         } else if (errno != EAGAIN) {
0154             return -1;
0155         }
0156     }
0157     return 0;
0158 }
0159 
0160 static int send_get_nfc_family(int sd, __u32 pid)
0161 {
0162     __u16 nla_get_family_type = CTRL_ATTR_FAMILY_NAME;
0163     void *nla_get_family_data;
0164     int nla_get_family_len;
0165     char family_name[100];
0166 
0167     nla_get_family_len = strlen(NFC_GENL_NAME) + 1;
0168     strcpy(family_name, NFC_GENL_NAME);
0169     nla_get_family_data = family_name;
0170 
0171     return send_cmd_mt_nla(sd, GENL_ID_CTRL, pid, CTRL_CMD_GETFAMILY,
0172                 1, &nla_get_family_type, &nla_get_family_data,
0173                 &nla_get_family_len, NLM_F_REQUEST);
0174 }
0175 
0176 static int get_family_id(int sd, __u32 pid, __u32 *event_group)
0177 {
0178     struct {
0179         struct nlmsghdr n;
0180         struct genlmsghdr g;
0181         char buf[512];
0182     } ans;
0183     struct nlattr *na;
0184     int resp_len;
0185     __u16 id;
0186     int len;
0187     int rc;
0188 
0189     rc = send_get_nfc_family(sd, pid);
0190 
0191     if (rc < 0)
0192         return 0;
0193 
0194     resp_len = recv(sd, &ans, sizeof(ans), 0);
0195 
0196     if (ans.n.nlmsg_type == NLMSG_ERROR || resp_len < 0 ||
0197         !NLMSG_OK(&ans.n, resp_len))
0198         return 0;
0199 
0200     len = 0;
0201     resp_len = GENLMSG_PAYLOAD(&ans.n);
0202     na = (struct nlattr *)GENLMSG_DATA(&ans);
0203 
0204     while (len < resp_len) {
0205         len += NLA_ALIGN(na->nla_len);
0206         if (na->nla_type == CTRL_ATTR_FAMILY_ID) {
0207             id = *(__u16 *)NLA_DATA(na);
0208         } else if (na->nla_type == CTRL_ATTR_MCAST_GROUPS) {
0209             struct nlattr *nested_na;
0210             struct nlattr *group_na;
0211             int group_attr_len;
0212             int group_attr;
0213 
0214             nested_na = (struct nlattr *)((char *)na + NLA_HDRLEN);
0215             group_na = (struct nlattr *)((char *)nested_na + NLA_HDRLEN);
0216             group_attr_len = 0;
0217 
0218             for (group_attr = CTRL_ATTR_MCAST_GRP_UNSPEC;
0219                 group_attr < CTRL_ATTR_MCAST_GRP_MAX; group_attr++) {
0220                 if (group_na->nla_type == CTRL_ATTR_MCAST_GRP_ID) {
0221                     *event_group = *(__u32 *)((char *)group_na +
0222                                   NLA_HDRLEN);
0223                     break;
0224                 }
0225 
0226                 group_attr_len += NLA_ALIGN(group_na->nla_len) +
0227                           NLA_HDRLEN;
0228                 if (group_attr_len >= nested_na->nla_len)
0229                     break;
0230 
0231                 group_na = (struct nlattr *)((char *)group_na +
0232                                  NLA_ALIGN(group_na->nla_len));
0233             }
0234         }
0235         na = (struct nlattr *)(GENLMSG_DATA(&ans) + len);
0236     }
0237     return id;
0238 }
0239 
0240 static int send_cmd_with_idx(int sd, __u16 nlmsg_type, __u32 nlmsg_pid,
0241                  __u8 genl_cmd, int dev_id)
0242 {
0243     __u16 nla_type = NFC_ATTR_DEVICE_INDEX;
0244     void *nla_data = &dev_id;
0245     int nla_len = 4;
0246 
0247     return send_cmd_mt_nla(sd, nlmsg_type, nlmsg_pid, genl_cmd, 1,
0248                 &nla_type, &nla_data, &nla_len, NLM_F_REQUEST);
0249 }
0250 
0251 static int get_nci_devid(int sd, __u16 fid, __u32 pid, int dev_id, struct msgtemplate *msg)
0252 {
0253     int rc, resp_len;
0254 
0255     rc = send_cmd_with_idx(sd, fid, pid, NFC_CMD_GET_DEVICE, dev_id);
0256     if (rc < 0) {
0257         rc = -1;
0258         goto error;
0259     }
0260 
0261     resp_len = recv(sd, msg, sizeof(*msg), 0);
0262     if (resp_len < 0) {
0263         rc = -2;
0264         goto error;
0265     }
0266 
0267     if (msg->n.nlmsg_type == NLMSG_ERROR ||
0268         !NLMSG_OK(&msg->n, resp_len)) {
0269         rc = -3;
0270         goto error;
0271     }
0272 
0273     return 0;
0274 error:
0275     return rc;
0276 }
0277 
0278 static __u8 get_dev_enable_state(struct msgtemplate *msg)
0279 {
0280     struct nlattr *na;
0281     int resp_len;
0282     int len;
0283 
0284     resp_len = GENLMSG_PAYLOAD(&msg->n);
0285     na = (struct nlattr *)GENLMSG_DATA(msg);
0286     len = 0;
0287 
0288     while (len < resp_len) {
0289         len += NLA_ALIGN(na->nla_len);
0290         if (na->nla_type == NFC_ATTR_DEVICE_POWERED)
0291             return *(char *)NLA_DATA(na);
0292         na = (struct nlattr *)(GENLMSG_DATA(msg) + len);
0293     }
0294 
0295     return resp_len;
0296 }
0297 
0298 FIXTURE(NCI) {
0299     int virtual_nci_fd;
0300     bool open_state;
0301     int dev_idex;
0302     bool isNCI2;
0303     int proto;
0304     __u32 pid;
0305     __u16 fid;
0306     int sd;
0307 };
0308 
0309 FIXTURE_VARIANT(NCI) {
0310     bool isNCI2;
0311 };
0312 
0313 FIXTURE_VARIANT_ADD(NCI, NCI1_0) {
0314     .isNCI2 = false,
0315 };
0316 
0317 FIXTURE_VARIANT_ADD(NCI, NCI2_0) {
0318     .isNCI2 = true,
0319 };
0320 
0321 static void *virtual_dev_open(void *data)
0322 {
0323     char buf[258];
0324     int dev_fd;
0325     int len;
0326 
0327     dev_fd = *(int *)data;
0328 
0329     len = read(dev_fd, buf, 258);
0330     if (len <= 0)
0331         goto error;
0332     if (len != sizeof(nci_reset_cmd))
0333         goto error;
0334     if (memcmp(nci_reset_cmd, buf, len))
0335         goto error;
0336     write(dev_fd, nci_reset_rsp, sizeof(nci_reset_rsp));
0337 
0338     len = read(dev_fd, buf, 258);
0339     if (len <= 0)
0340         goto error;
0341     if (len != sizeof(nci_init_cmd))
0342         goto error;
0343     if (memcmp(nci_init_cmd, buf, len))
0344         goto error;
0345     write(dev_fd, nci_init_rsp, sizeof(nci_init_rsp));
0346 
0347     len = read(dev_fd, buf, 258);
0348     if (len <= 0)
0349         goto error;
0350     if (len != sizeof(nci_rf_disc_map_cmd))
0351         goto error;
0352     if (memcmp(nci_rf_disc_map_cmd, buf, len))
0353         goto error;
0354     write(dev_fd, nci_rf_disc_map_rsp, sizeof(nci_rf_disc_map_rsp));
0355 
0356     return (void *)0;
0357 error:
0358     return (void *)-1;
0359 }
0360 
0361 static void *virtual_dev_open_v2(void *data)
0362 {
0363     char buf[258];
0364     int dev_fd;
0365     int len;
0366 
0367     dev_fd = *(int *)data;
0368 
0369     len = read(dev_fd, buf, 258);
0370     if (len <= 0)
0371         goto error;
0372     if (len != sizeof(nci_reset_cmd))
0373         goto error;
0374     if (memcmp(nci_reset_cmd, buf, len))
0375         goto error;
0376     write(dev_fd, nci_reset_rsp_v2, sizeof(nci_reset_rsp_v2));
0377     write(dev_fd, nci_reset_ntf, sizeof(nci_reset_ntf));
0378 
0379     len = read(dev_fd, buf, 258);
0380     if (len <= 0)
0381         goto error;
0382     if (len != sizeof(nci_init_cmd_v2))
0383         goto error;
0384     if (memcmp(nci_init_cmd_v2, buf, len))
0385         goto error;
0386     write(dev_fd, nci_init_rsp_v2, sizeof(nci_init_rsp_v2));
0387 
0388     len = read(dev_fd, buf, 258);
0389     if (len <= 0)
0390         goto error;
0391     if (len != sizeof(nci_rf_disc_map_cmd))
0392         goto error;
0393     if (memcmp(nci_rf_disc_map_cmd, buf, len))
0394         goto error;
0395     write(dev_fd, nci_rf_disc_map_rsp, sizeof(nci_rf_disc_map_rsp));
0396 
0397     return (void *)0;
0398 error:
0399     return (void *)-1;
0400 }
0401 
0402 FIXTURE_SETUP(NCI)
0403 {
0404     struct msgtemplate msg;
0405     pthread_t thread_t;
0406     __u32 event_group;
0407     int status;
0408     int rc;
0409 
0410     self->open_state = false;
0411     self->proto = VIRTUAL_NFC_PROTOCOLS;
0412     self->isNCI2 = variant->isNCI2;
0413 
0414     self->sd = create_nl_socket();
0415     ASSERT_NE(self->sd, -1);
0416 
0417     self->pid = getpid();
0418     self->fid = get_family_id(self->sd, self->pid, &event_group);
0419     ASSERT_NE(self->fid, -1);
0420 
0421     self->virtual_nci_fd = open("/dev/virtual_nci", O_RDWR);
0422     ASSERT_GT(self->virtual_nci_fd, -1);
0423 
0424     rc = setsockopt(self->sd, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, &event_group,
0425             sizeof(event_group));
0426     ASSERT_NE(rc, -1);
0427 
0428     rc = ioctl(self->virtual_nci_fd, IOCTL_GET_NCIDEV_IDX, &self->dev_idex);
0429     ASSERT_EQ(rc, 0);
0430 
0431     rc = get_nci_devid(self->sd, self->fid, self->pid, self->dev_idex, &msg);
0432     ASSERT_EQ(rc, 0);
0433     EXPECT_EQ(get_dev_enable_state(&msg), 0);
0434 
0435     if (self->isNCI2)
0436         rc = pthread_create(&thread_t, NULL, virtual_dev_open_v2,
0437                     (void *)&self->virtual_nci_fd);
0438     else
0439         rc = pthread_create(&thread_t, NULL, virtual_dev_open,
0440                     (void *)&self->virtual_nci_fd);
0441     ASSERT_GT(rc, -1);
0442 
0443     rc = send_cmd_with_idx(self->sd, self->fid, self->pid,
0444                    NFC_CMD_DEV_UP, self->dev_idex);
0445     EXPECT_EQ(rc, 0);
0446 
0447     pthread_join(thread_t, (void **)&status);
0448     ASSERT_EQ(status, 0);
0449     self->open_state = true;
0450 }
0451 
0452 static void *virtual_deinit(void *data)
0453 {
0454     char buf[258];
0455     int dev_fd;
0456     int len;
0457 
0458     dev_fd = *(int *)data;
0459 
0460     len = read(dev_fd, buf, 258);
0461     if (len <= 0)
0462         goto error;
0463     if (len != sizeof(nci_reset_cmd))
0464         goto error;
0465     if (memcmp(nci_reset_cmd, buf, len))
0466         goto error;
0467     write(dev_fd, nci_reset_rsp, sizeof(nci_reset_rsp));
0468 
0469     return (void *)0;
0470 error:
0471     return (void *)-1;
0472 }
0473 
0474 static void *virtual_deinit_v2(void *data)
0475 {
0476     char buf[258];
0477     int dev_fd;
0478     int len;
0479 
0480     dev_fd = *(int *)data;
0481 
0482     len = read(dev_fd, buf, 258);
0483     if (len <= 0)
0484         goto error;
0485     if (len != sizeof(nci_reset_cmd))
0486         goto error;
0487     if (memcmp(nci_reset_cmd, buf, len))
0488         goto error;
0489     write(dev_fd, nci_reset_rsp_v2, sizeof(nci_reset_rsp_v2));
0490     write(dev_fd, nci_reset_ntf, sizeof(nci_reset_ntf));
0491 
0492     return (void *)0;
0493 error:
0494     return (void *)-1;
0495 }
0496 
0497 FIXTURE_TEARDOWN(NCI)
0498 {
0499     pthread_t thread_t;
0500     int status;
0501     int rc;
0502 
0503     if (self->open_state) {
0504         if (self->isNCI2)
0505             rc = pthread_create(&thread_t, NULL,
0506                         virtual_deinit_v2,
0507                         (void *)&self->virtual_nci_fd);
0508         else
0509             rc = pthread_create(&thread_t, NULL, virtual_deinit,
0510                         (void *)&self->virtual_nci_fd);
0511 
0512         ASSERT_GT(rc, -1);
0513         rc = send_cmd_with_idx(self->sd, self->fid, self->pid,
0514                        NFC_CMD_DEV_DOWN, self->dev_idex);
0515         EXPECT_EQ(rc, 0);
0516 
0517         pthread_join(thread_t, (void **)&status);
0518         ASSERT_EQ(status, 0);
0519     }
0520 
0521     close(self->sd);
0522     close(self->virtual_nci_fd);
0523     self->open_state = false;
0524 }
0525 
0526 TEST_F(NCI, init)
0527 {
0528     struct msgtemplate msg;
0529     int rc;
0530 
0531     rc = get_nci_devid(self->sd, self->fid, self->pid, self->dev_idex,
0532                &msg);
0533     ASSERT_EQ(rc, 0);
0534     EXPECT_EQ(get_dev_enable_state(&msg), 1);
0535 }
0536 
0537 static void *virtual_poll_start(void *data)
0538 {
0539     char buf[258];
0540     int dev_fd;
0541     int len;
0542 
0543     dev_fd = *(int *)data;
0544 
0545     len = read(dev_fd, buf, 258);
0546     if (len <= 0)
0547         goto error;
0548     if (len != sizeof(nci_rf_discovery_cmd))
0549         goto error;
0550     if (memcmp(nci_rf_discovery_cmd, buf, len))
0551         goto error;
0552     write(dev_fd, nci_rf_disc_rsp, sizeof(nci_rf_disc_rsp));
0553 
0554     return (void *)0;
0555 error:
0556     return (void *)-1;
0557 }
0558 
0559 static void *virtual_poll_stop(void *data)
0560 {
0561     char buf[258];
0562     int dev_fd;
0563     int len;
0564 
0565     dev_fd = *(int *)data;
0566 
0567     len = read(dev_fd, buf, 258);
0568     if (len <= 0)
0569         goto error;
0570     if (len != sizeof(nci_rf_deact_cmd))
0571         goto error;
0572     if (memcmp(nci_rf_deact_cmd, buf, len))
0573         goto error;
0574     write(dev_fd, nci_rf_deact_rsp, sizeof(nci_rf_deact_rsp));
0575 
0576     return (void *)0;
0577 error:
0578     return (void *)-1;
0579 }
0580 
0581 int start_polling(int dev_idx, int proto, int virtual_fd, int sd, int fid, int pid)
0582 {
0583     __u16 nla_start_poll_type[2] = {NFC_ATTR_DEVICE_INDEX,
0584                      NFC_ATTR_PROTOCOLS};
0585     void *nla_start_poll_data[2] = {&dev_idx, &proto};
0586     int nla_start_poll_len[2] = {4, 4};
0587     pthread_t thread_t;
0588     int status;
0589     int rc;
0590 
0591     rc = pthread_create(&thread_t, NULL, virtual_poll_start,
0592                 (void *)&virtual_fd);
0593     if (rc < 0)
0594         return rc;
0595 
0596     rc = send_cmd_mt_nla(sd, fid, pid, NFC_CMD_START_POLL, 2, nla_start_poll_type,
0597                  nla_start_poll_data, nla_start_poll_len, NLM_F_REQUEST);
0598     if (rc != 0)
0599         return rc;
0600 
0601     pthread_join(thread_t, (void **)&status);
0602     return status;
0603 }
0604 
0605 int stop_polling(int dev_idx, int virtual_fd, int sd, int fid, int pid)
0606 {
0607     pthread_t thread_t;
0608     int status;
0609     int rc;
0610 
0611     rc = pthread_create(&thread_t, NULL, virtual_poll_stop,
0612                 (void *)&virtual_fd);
0613     if (rc < 0)
0614         return rc;
0615 
0616     rc = send_cmd_with_idx(sd, fid, pid,
0617                    NFC_CMD_STOP_POLL, dev_idx);
0618     if (rc != 0)
0619         return rc;
0620 
0621     pthread_join(thread_t, (void **)&status);
0622     return status;
0623 }
0624 
0625 TEST_F(NCI, start_poll)
0626 {
0627     int status;
0628 
0629     status = start_polling(self->dev_idex, self->proto, self->virtual_nci_fd,
0630                    self->sd, self->fid, self->pid);
0631     EXPECT_EQ(status, 0);
0632 
0633     status = stop_polling(self->dev_idex, self->virtual_nci_fd, self->sd,
0634                   self->fid, self->pid);
0635     EXPECT_EQ(status, 0);
0636 }
0637 
0638 int get_taginfo(int dev_idx, int sd, int fid, int pid)
0639 {
0640     struct {
0641         struct nlmsghdr n;
0642         struct genlmsghdr g;
0643         char buf[512];
0644     } ans;
0645 
0646     struct nlattr *na;
0647     __u32 protocol;
0648     int targetidx;
0649     __u8 sel_res;
0650     int resp_len;
0651     int len;
0652 
0653     __u16 tagid_type;
0654     void *tagid_type_data;
0655     int tagid_len;
0656 
0657     tagid_type = NFC_ATTR_DEVICE_INDEX;
0658     tagid_type_data = &dev_idx;
0659     tagid_len = 4;
0660 
0661     send_cmd_mt_nla(sd, fid, pid, NFC_CMD_GET_TARGET, 1, &tagid_type,
0662             &tagid_type_data, &tagid_len, NLM_F_REQUEST | NLM_F_DUMP);
0663     resp_len = recv(sd, &ans, sizeof(ans), 0);
0664     if (ans.n.nlmsg_type == NLMSG_ERROR || resp_len < 0 ||
0665         !NLMSG_OK(&ans.n, resp_len))
0666         return -1;
0667 
0668     resp_len = GENLMSG_PAYLOAD(&ans.n);
0669     na = (struct nlattr *)GENLMSG_DATA(&ans);
0670 
0671     len = 0;
0672     targetidx = -1;
0673     protocol = -1;
0674     sel_res = -1;
0675 
0676     while (len < resp_len) {
0677         len += NLA_ALIGN(na->nla_len);
0678 
0679         if (na->nla_type == NFC_ATTR_TARGET_INDEX)
0680             targetidx = *(int *)((char *)na + NLA_HDRLEN);
0681         else if (na->nla_type == NFC_ATTR_TARGET_SEL_RES)
0682             sel_res = *(__u8 *)((char *)na + NLA_HDRLEN);
0683         else if (na->nla_type == NFC_ATTR_PROTOCOLS)
0684             protocol = *(__u32 *)((char *)na + NLA_HDRLEN);
0685 
0686         na = (struct nlattr *)(GENLMSG_DATA(&ans) + len);
0687     }
0688 
0689     if (targetidx == -1 || sel_res != 0x20 || protocol != NFC_PROTO_ISO14443_MASK)
0690         return -1;
0691 
0692     return targetidx;
0693 }
0694 
0695 int connect_socket(int dev_idx, int target_idx)
0696 {
0697     struct sockaddr_nfc addr;
0698     int sock;
0699     int err = 0;
0700 
0701     sock = socket(AF_NFC, SOCK_SEQPACKET, NFC_SOCKPROTO_RAW);
0702     if (sock == -1)
0703         return -1;
0704 
0705     addr.sa_family = AF_NFC;
0706     addr.dev_idx = dev_idx;
0707     addr.target_idx = target_idx;
0708     addr.nfc_protocol = NFC_PROTO_ISO14443;
0709 
0710     err = connect(sock, (struct sockaddr *)&addr, sizeof(addr));
0711     if (err) {
0712         close(sock);
0713         return -1;
0714     }
0715 
0716     return sock;
0717 }
0718 
0719 int connect_tag(int dev_idx, int virtual_fd, int sd, int fid, int pid)
0720 {
0721     struct genlmsghdr *genlhdr;
0722     struct nlattr *na;
0723     char evt_data[255];
0724     int target_idx;
0725     int resp_len;
0726     int evt_dev;
0727 
0728     write(virtual_fd, nci_rf_activate_ntf, sizeof(nci_rf_activate_ntf));
0729     resp_len = recv(sd, evt_data, sizeof(evt_data), 0);
0730     if (resp_len < 0)
0731         return -1;
0732 
0733     genlhdr = (struct genlmsghdr *)((struct nlmsghdr *)evt_data + 1);
0734     na = (struct nlattr *)(genlhdr + 1);
0735     evt_dev = *(int *)((char *)na + NLA_HDRLEN);
0736     if (dev_idx != evt_dev)
0737         return -1;
0738 
0739     target_idx = get_taginfo(dev_idx, sd, fid, pid);
0740     if (target_idx == -1)
0741         return -1;
0742     return connect_socket(dev_idx, target_idx);
0743 }
0744 
0745 int read_write_nci_cmd(int nfc_sock, int virtual_fd, const __u8 *cmd, __u32 cmd_len,
0746                const __u8 *rsp, __u32 rsp_len)
0747 {
0748     char buf[256];
0749     int len;
0750 
0751     send(nfc_sock, &cmd[3], cmd_len - 3, 0);
0752     len = read(virtual_fd, buf, cmd_len);
0753     if (len < 0 || memcmp(buf, cmd, cmd_len))
0754         return -1;
0755 
0756     write(virtual_fd, rsp, rsp_len);
0757     len = recv(nfc_sock, buf, rsp_len - 2, 0);
0758     if (len < 0 || memcmp(&buf[1], &rsp[3], rsp_len - 3))
0759         return -1;
0760 
0761     return 0;
0762 }
0763 
0764 int read_tag(int nfc_sock, int virtual_fd)
0765 {
0766     if (read_write_nci_cmd(nfc_sock, virtual_fd, nci_t4t_select_cmd,
0767                    sizeof(nci_t4t_select_cmd), nci_t4t_rsp_ok,
0768                    sizeof(nci_t4t_rsp_ok)))
0769         return -1;
0770 
0771     if (read_write_nci_cmd(nfc_sock, virtual_fd, nci_t4t_select_cmd2,
0772                    sizeof(nci_t4t_select_cmd2), nci_t4t_rsp_ok,
0773                    sizeof(nci_t4t_rsp_ok)))
0774         return -1;
0775 
0776     if (read_write_nci_cmd(nfc_sock, virtual_fd, nci_t4t_read_cmd,
0777                    sizeof(nci_t4t_read_cmd), nci_t4t_read_rsp,
0778                    sizeof(nci_t4t_read_rsp)))
0779         return -1;
0780 
0781     if (read_write_nci_cmd(nfc_sock, virtual_fd, nci_t4t_select_cmd3,
0782                    sizeof(nci_t4t_select_cmd3), nci_t4t_rsp_ok,
0783                    sizeof(nci_t4t_rsp_ok)))
0784         return -1;
0785 
0786     if (read_write_nci_cmd(nfc_sock, virtual_fd, nci_t4t_read_cmd2,
0787                    sizeof(nci_t4t_read_cmd2), nci_t4t_read_rsp2,
0788                    sizeof(nci_t4t_read_rsp2)))
0789         return -1;
0790 
0791     return read_write_nci_cmd(nfc_sock, virtual_fd, nci_t4t_read_cmd3,
0792                   sizeof(nci_t4t_read_cmd3), nci_t4t_read_rsp3,
0793                   sizeof(nci_t4t_read_rsp3));
0794 }
0795 
0796 static void *virtual_deactivate_proc(void *data)
0797 {
0798     int virtual_fd;
0799     char buf[256];
0800     int deactcmd_len;
0801     int len;
0802 
0803     virtual_fd = *(int *)data;
0804     deactcmd_len = sizeof(nci_rf_deact_cmd);
0805     len = read(virtual_fd, buf, deactcmd_len);
0806     if (len != deactcmd_len || memcmp(buf, nci_rf_deact_cmd, deactcmd_len))
0807         return (void *)-1;
0808 
0809     write(virtual_fd, nci_rf_deact_rsp, sizeof(nci_rf_deact_rsp));
0810     write(virtual_fd, nci_rf_deact_ntf, sizeof(nci_rf_deact_ntf));
0811 
0812     return (void *)0;
0813 }
0814 
0815 int disconnect_tag(int nfc_sock, int virtual_fd)
0816 {
0817     pthread_t thread_t;
0818     char buf[256];
0819     int status;
0820     int len;
0821 
0822     send(nfc_sock, &nci_t4t_select_cmd3[3], sizeof(nci_t4t_select_cmd3) - 3, 0);
0823     len = read(virtual_fd, buf, sizeof(nci_t4t_select_cmd3));
0824     if (len < 0 || memcmp(buf, nci_t4t_select_cmd3, sizeof(nci_t4t_select_cmd3)))
0825         return -1;
0826 
0827     len = recv(nfc_sock, buf, sizeof(nci_t4t_rsp_ok), 0);
0828     if (len != -1)
0829         return -1;
0830 
0831     status = pthread_create(&thread_t, NULL, virtual_deactivate_proc,
0832                 (void *)&virtual_fd);
0833 
0834     close(nfc_sock);
0835     pthread_join(thread_t, (void **)&status);
0836     return status;
0837 }
0838 
0839 TEST_F(NCI, t4t_tag_read)
0840 {
0841     int nfc_sock;
0842     int status;
0843 
0844     status = start_polling(self->dev_idex, self->proto, self->virtual_nci_fd,
0845                    self->sd, self->fid, self->pid);
0846     EXPECT_EQ(status, 0);
0847 
0848     nfc_sock = connect_tag(self->dev_idex, self->virtual_nci_fd, self->sd,
0849                    self->fid, self->pid);
0850     ASSERT_GT(nfc_sock, -1);
0851 
0852     status = read_tag(nfc_sock, self->virtual_nci_fd);
0853     ASSERT_EQ(status, 0);
0854 
0855     status = disconnect_tag(nfc_sock, self->virtual_nci_fd);
0856     EXPECT_EQ(status, 0);
0857 }
0858 
0859 TEST_F(NCI, deinit)
0860 {
0861     struct msgtemplate msg;
0862     pthread_t thread_t;
0863     int status;
0864     int rc;
0865 
0866     rc = get_nci_devid(self->sd, self->fid, self->pid, self->dev_idex,
0867                &msg);
0868     ASSERT_EQ(rc, 0);
0869     EXPECT_EQ(get_dev_enable_state(&msg), 1);
0870 
0871     if (self->isNCI2)
0872         rc = pthread_create(&thread_t, NULL, virtual_deinit_v2,
0873                     (void *)&self->virtual_nci_fd);
0874     else
0875         rc = pthread_create(&thread_t, NULL, virtual_deinit,
0876                     (void *)&self->virtual_nci_fd);
0877     ASSERT_GT(rc, -1);
0878 
0879     rc = send_cmd_with_idx(self->sd, self->fid, self->pid,
0880                    NFC_CMD_DEV_DOWN, self->dev_idex);
0881     EXPECT_EQ(rc, 0);
0882 
0883     pthread_join(thread_t, (void **)&status);
0884     self->open_state = 0;
0885     ASSERT_EQ(status, 0);
0886 
0887     rc = get_nci_devid(self->sd, self->fid, self->pid, self->dev_idex,
0888                &msg);
0889     ASSERT_EQ(rc, 0);
0890     EXPECT_EQ(get_dev_enable_state(&msg), 0);
0891 }
0892 
0893 TEST_HARNESS_MAIN