1 /* 2 * Copyright (C) 2011 Instituto Nokia de Tecnologia 3 * 4 * Authors: 5 * Lauro Ramos Venancio <lauro.venancio@openbossa.org> 6 * Aloisio Almeida Jr <aloisio.almeida@openbossa.org> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the 20 * Free Software Foundation, Inc., 21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 22 */ 23 24 #include <net/genetlink.h> 25 #include <linux/nfc.h> 26 #include <linux/slab.h> 27 28 #include "nfc.h" 29 30 static struct genl_multicast_group nfc_genl_event_mcgrp = { 31 .name = NFC_GENL_MCAST_EVENT_NAME, 32 }; 33 34 struct genl_family nfc_genl_family = { 35 .id = GENL_ID_GENERATE, 36 .hdrsize = 0, 37 .name = NFC_GENL_NAME, 38 .version = NFC_GENL_VERSION, 39 .maxattr = NFC_ATTR_MAX, 40 }; 41 42 static const struct nla_policy nfc_genl_policy[NFC_ATTR_MAX + 1] = { 43 [NFC_ATTR_DEVICE_INDEX] = { .type = NLA_U32 }, 44 [NFC_ATTR_DEVICE_NAME] = { .type = NLA_STRING, 45 .len = NFC_DEVICE_NAME_MAXSIZE }, 46 [NFC_ATTR_PROTOCOLS] = { .type = NLA_U32 }, 47 }; 48 49 static int nfc_genl_send_target(struct sk_buff *msg, struct nfc_target *target, 50 struct netlink_callback *cb, int flags) 51 { 52 void *hdr; 53 54 nfc_dbg("entry"); 55 56 hdr = genlmsg_put(msg, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, 57 &nfc_genl_family, flags, NFC_CMD_GET_TARGET); 58 if (!hdr) 59 return -EMSGSIZE; 60 61 genl_dump_check_consistent(cb, hdr, &nfc_genl_family); 62 63 NLA_PUT_U32(msg, NFC_ATTR_TARGET_INDEX, target->idx); 64 NLA_PUT_U32(msg, NFC_ATTR_PROTOCOLS, 65 target->supported_protocols); 66 NLA_PUT_U16(msg, NFC_ATTR_TARGET_SENS_RES, target->sens_res); 67 NLA_PUT_U8(msg, NFC_ATTR_TARGET_SEL_RES, target->sel_res); 68 69 return genlmsg_end(msg, hdr); 70 71 nla_put_failure: 72 genlmsg_cancel(msg, hdr); 73 return -EMSGSIZE; 74 } 75 76 static struct nfc_dev *__get_device_from_cb(struct netlink_callback *cb) 77 { 78 struct nfc_dev *dev; 79 int rc; 80 u32 idx; 81 82 rc = nlmsg_parse(cb->nlh, GENL_HDRLEN + nfc_genl_family.hdrsize, 83 nfc_genl_family.attrbuf, 84 nfc_genl_family.maxattr, 85 nfc_genl_policy); 86 if (rc < 0) 87 return ERR_PTR(rc); 88 89 if (!nfc_genl_family.attrbuf[NFC_ATTR_DEVICE_INDEX]) 90 return ERR_PTR(-EINVAL); 91 92 idx = nla_get_u32(nfc_genl_family.attrbuf[NFC_ATTR_DEVICE_INDEX]); 93 94 dev = nfc_get_device(idx); 95 if (!dev) 96 return ERR_PTR(-ENODEV); 97 98 return dev; 99 } 100 101 static int nfc_genl_dump_targets(struct sk_buff *skb, 102 struct netlink_callback *cb) 103 { 104 int i = cb->args[0]; 105 struct nfc_dev *dev = (struct nfc_dev *) cb->args[1]; 106 int rc; 107 108 nfc_dbg("entry"); 109 110 if (!dev) { 111 dev = __get_device_from_cb(cb); 112 if (IS_ERR(dev)) 113 return PTR_ERR(dev); 114 115 cb->args[1] = (long) dev; 116 } 117 118 spin_lock_bh(&dev->targets_lock); 119 120 cb->seq = dev->targets_generation; 121 122 while (i < dev->n_targets) { 123 rc = nfc_genl_send_target(skb, &dev->targets[i], cb, 124 NLM_F_MULTI); 125 if (rc < 0) 126 break; 127 128 i++; 129 } 130 131 spin_unlock_bh(&dev->targets_lock); 132 133 cb->args[0] = i; 134 135 return skb->len; 136 } 137 138 static int nfc_genl_dump_targets_done(struct netlink_callback *cb) 139 { 140 struct nfc_dev *dev = (struct nfc_dev *) cb->args[1]; 141 142 nfc_dbg("entry"); 143 144 if (dev) 145 nfc_put_device(dev); 146 147 return 0; 148 } 149 150 int nfc_genl_targets_found(struct nfc_dev *dev) 151 { 152 struct sk_buff *msg; 153 void *hdr; 154 155 nfc_dbg("entry"); 156 157 dev->genl_data.poll_req_pid = 0; 158 159 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC); 160 if (!msg) 161 return -ENOMEM; 162 163 hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0, 164 NFC_EVENT_TARGETS_FOUND); 165 if (!hdr) 166 goto free_msg; 167 168 NLA_PUT_U32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx); 169 170 genlmsg_end(msg, hdr); 171 172 return genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_ATOMIC); 173 174 nla_put_failure: 175 genlmsg_cancel(msg, hdr); 176 free_msg: 177 nlmsg_free(msg); 178 return -EMSGSIZE; 179 } 180 181 int nfc_genl_device_added(struct nfc_dev *dev) 182 { 183 struct sk_buff *msg; 184 void *hdr; 185 186 nfc_dbg("entry"); 187 188 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); 189 if (!msg) 190 return -ENOMEM; 191 192 hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0, 193 NFC_EVENT_DEVICE_ADDED); 194 if (!hdr) 195 goto free_msg; 196 197 NLA_PUT_STRING(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev)); 198 NLA_PUT_U32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx); 199 NLA_PUT_U32(msg, NFC_ATTR_PROTOCOLS, dev->supported_protocols); 200 201 genlmsg_end(msg, hdr); 202 203 genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_KERNEL); 204 205 return 0; 206 207 nla_put_failure: 208 genlmsg_cancel(msg, hdr); 209 free_msg: 210 nlmsg_free(msg); 211 return -EMSGSIZE; 212 } 213 214 int nfc_genl_device_removed(struct nfc_dev *dev) 215 { 216 struct sk_buff *msg; 217 void *hdr; 218 219 nfc_dbg("entry"); 220 221 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); 222 if (!msg) 223 return -ENOMEM; 224 225 hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0, 226 NFC_EVENT_DEVICE_REMOVED); 227 if (!hdr) 228 goto free_msg; 229 230 NLA_PUT_U32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx); 231 232 genlmsg_end(msg, hdr); 233 234 genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_KERNEL); 235 236 return 0; 237 238 nla_put_failure: 239 genlmsg_cancel(msg, hdr); 240 free_msg: 241 nlmsg_free(msg); 242 return -EMSGSIZE; 243 } 244 245 static int nfc_genl_send_device(struct sk_buff *msg, struct nfc_dev *dev, 246 u32 pid, u32 seq, 247 struct netlink_callback *cb, 248 int flags) 249 { 250 void *hdr; 251 252 nfc_dbg("entry"); 253 254 hdr = genlmsg_put(msg, pid, seq, &nfc_genl_family, flags, 255 NFC_CMD_GET_DEVICE); 256 if (!hdr) 257 return -EMSGSIZE; 258 259 if (cb) 260 genl_dump_check_consistent(cb, hdr, &nfc_genl_family); 261 262 NLA_PUT_STRING(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev)); 263 NLA_PUT_U32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx); 264 NLA_PUT_U32(msg, NFC_ATTR_PROTOCOLS, dev->supported_protocols); 265 266 return genlmsg_end(msg, hdr); 267 268 nla_put_failure: 269 genlmsg_cancel(msg, hdr); 270 return -EMSGSIZE; 271 } 272 273 static int nfc_genl_dump_devices(struct sk_buff *skb, 274 struct netlink_callback *cb) 275 { 276 struct class_dev_iter *iter = (struct class_dev_iter *) cb->args[0]; 277 struct nfc_dev *dev = (struct nfc_dev *) cb->args[1]; 278 bool first_call = false; 279 280 nfc_dbg("entry"); 281 282 if (!iter) { 283 first_call = true; 284 iter = kmalloc(sizeof(struct class_dev_iter), GFP_KERNEL); 285 if (!iter) 286 return -ENOMEM; 287 cb->args[0] = (long) iter; 288 } 289 290 mutex_lock(&nfc_devlist_mutex); 291 292 cb->seq = nfc_devlist_generation; 293 294 if (first_call) { 295 nfc_device_iter_init(iter); 296 dev = nfc_device_iter_next(iter); 297 } 298 299 while (dev) { 300 int rc; 301 302 rc = nfc_genl_send_device(skb, dev, NETLINK_CB(cb->skb).pid, 303 cb->nlh->nlmsg_seq, 304 cb, NLM_F_MULTI); 305 if (rc < 0) 306 break; 307 308 dev = nfc_device_iter_next(iter); 309 } 310 311 mutex_unlock(&nfc_devlist_mutex); 312 313 cb->args[1] = (long) dev; 314 315 return skb->len; 316 } 317 318 static int nfc_genl_dump_devices_done(struct netlink_callback *cb) 319 { 320 struct class_dev_iter *iter = (struct class_dev_iter *) cb->args[0]; 321 322 nfc_dbg("entry"); 323 324 nfc_device_iter_exit(iter); 325 kfree(iter); 326 327 return 0; 328 } 329 330 static int nfc_genl_get_device(struct sk_buff *skb, struct genl_info *info) 331 { 332 struct sk_buff *msg; 333 struct nfc_dev *dev; 334 u32 idx; 335 int rc = -ENOBUFS; 336 337 nfc_dbg("entry"); 338 339 if (!info->attrs[NFC_ATTR_DEVICE_INDEX]) 340 return -EINVAL; 341 342 idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]); 343 344 dev = nfc_get_device(idx); 345 if (!dev) 346 return -ENODEV; 347 348 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); 349 if (!msg) { 350 rc = -ENOMEM; 351 goto out_putdev; 352 } 353 354 rc = nfc_genl_send_device(msg, dev, info->snd_pid, info->snd_seq, 355 NULL, 0); 356 if (rc < 0) 357 goto out_free; 358 359 nfc_put_device(dev); 360 361 return genlmsg_reply(msg, info); 362 363 out_free: 364 nlmsg_free(msg); 365 out_putdev: 366 nfc_put_device(dev); 367 return rc; 368 } 369 370 static int nfc_genl_start_poll(struct sk_buff *skb, struct genl_info *info) 371 { 372 struct nfc_dev *dev; 373 int rc; 374 u32 idx; 375 u32 protocols; 376 377 nfc_dbg("entry"); 378 379 if (!info->attrs[NFC_ATTR_DEVICE_INDEX] || 380 !info->attrs[NFC_ATTR_PROTOCOLS]) 381 return -EINVAL; 382 383 idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]); 384 protocols = nla_get_u32(info->attrs[NFC_ATTR_PROTOCOLS]); 385 386 dev = nfc_get_device(idx); 387 if (!dev) 388 return -ENODEV; 389 390 mutex_lock(&dev->genl_data.genl_data_mutex); 391 392 rc = nfc_start_poll(dev, protocols); 393 if (!rc) 394 dev->genl_data.poll_req_pid = info->snd_pid; 395 396 mutex_unlock(&dev->genl_data.genl_data_mutex); 397 398 nfc_put_device(dev); 399 return rc; 400 } 401 402 static int nfc_genl_stop_poll(struct sk_buff *skb, struct genl_info *info) 403 { 404 struct nfc_dev *dev; 405 int rc; 406 u32 idx; 407 408 nfc_dbg("entry"); 409 410 if (!info->attrs[NFC_ATTR_DEVICE_INDEX]) 411 return -EINVAL; 412 413 idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]); 414 415 dev = nfc_get_device(idx); 416 if (!dev) 417 return -ENODEV; 418 419 mutex_lock(&dev->genl_data.genl_data_mutex); 420 421 if (dev->genl_data.poll_req_pid != info->snd_pid) { 422 rc = -EBUSY; 423 goto out; 424 } 425 426 rc = nfc_stop_poll(dev); 427 dev->genl_data.poll_req_pid = 0; 428 429 out: 430 mutex_unlock(&dev->genl_data.genl_data_mutex); 431 nfc_put_device(dev); 432 return rc; 433 } 434 435 static struct genl_ops nfc_genl_ops[] = { 436 { 437 .cmd = NFC_CMD_GET_DEVICE, 438 .doit = nfc_genl_get_device, 439 .dumpit = nfc_genl_dump_devices, 440 .done = nfc_genl_dump_devices_done, 441 .policy = nfc_genl_policy, 442 }, 443 { 444 .cmd = NFC_CMD_START_POLL, 445 .doit = nfc_genl_start_poll, 446 .policy = nfc_genl_policy, 447 }, 448 { 449 .cmd = NFC_CMD_STOP_POLL, 450 .doit = nfc_genl_stop_poll, 451 .policy = nfc_genl_policy, 452 }, 453 { 454 .cmd = NFC_CMD_GET_TARGET, 455 .dumpit = nfc_genl_dump_targets, 456 .done = nfc_genl_dump_targets_done, 457 .policy = nfc_genl_policy, 458 }, 459 }; 460 461 static int nfc_genl_rcv_nl_event(struct notifier_block *this, 462 unsigned long event, void *ptr) 463 { 464 struct netlink_notify *n = ptr; 465 struct class_dev_iter iter; 466 struct nfc_dev *dev; 467 468 if (event != NETLINK_URELEASE || n->protocol != NETLINK_GENERIC) 469 goto out; 470 471 nfc_dbg("NETLINK_URELEASE event from id %d", n->pid); 472 473 nfc_device_iter_init(&iter); 474 dev = nfc_device_iter_next(&iter); 475 476 while (dev) { 477 mutex_lock(&dev->genl_data.genl_data_mutex); 478 if (dev->genl_data.poll_req_pid == n->pid) { 479 nfc_stop_poll(dev); 480 dev->genl_data.poll_req_pid = 0; 481 } 482 mutex_unlock(&dev->genl_data.genl_data_mutex); 483 dev = nfc_device_iter_next(&iter); 484 } 485 486 nfc_device_iter_exit(&iter); 487 488 out: 489 return NOTIFY_DONE; 490 } 491 492 void nfc_genl_data_init(struct nfc_genl_data *genl_data) 493 { 494 genl_data->poll_req_pid = 0; 495 mutex_init(&genl_data->genl_data_mutex); 496 } 497 498 void nfc_genl_data_exit(struct nfc_genl_data *genl_data) 499 { 500 mutex_destroy(&genl_data->genl_data_mutex); 501 } 502 503 static struct notifier_block nl_notifier = { 504 .notifier_call = nfc_genl_rcv_nl_event, 505 }; 506 507 /** 508 * nfc_genl_init() - Initialize netlink interface 509 * 510 * This initialization function registers the nfc netlink family. 511 */ 512 int __init nfc_genl_init(void) 513 { 514 int rc; 515 516 rc = genl_register_family_with_ops(&nfc_genl_family, nfc_genl_ops, 517 ARRAY_SIZE(nfc_genl_ops)); 518 if (rc) 519 return rc; 520 521 rc = genl_register_mc_group(&nfc_genl_family, &nfc_genl_event_mcgrp); 522 523 netlink_register_notifier(&nl_notifier); 524 525 return rc; 526 } 527 528 /** 529 * nfc_genl_exit() - Deinitialize netlink interface 530 * 531 * This exit function unregisters the nfc netlink family. 532 */ 533 void nfc_genl_exit(void) 534 { 535 netlink_unregister_notifier(&nl_notifier); 536 genl_unregister_family(&nfc_genl_family); 537 } 538