nci_dev.c 21 KB

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