Linux Audio

Check our new training course

Loading...
v3.5.6
  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#define pr_fmt(fmt) KBUILD_MODNAME ": %s: " fmt, __func__
 25
 26#include <net/genetlink.h>
 27#include <linux/nfc.h>
 28#include <linux/slab.h>
 29
 30#include "nfc.h"
 31
 32static struct genl_multicast_group nfc_genl_event_mcgrp = {
 33	.name = NFC_GENL_MCAST_EVENT_NAME,
 34};
 35
 36static struct genl_family nfc_genl_family = {
 37	.id = GENL_ID_GENERATE,
 38	.hdrsize = 0,
 39	.name = NFC_GENL_NAME,
 40	.version = NFC_GENL_VERSION,
 41	.maxattr = NFC_ATTR_MAX,
 42};
 43
 44static const struct nla_policy nfc_genl_policy[NFC_ATTR_MAX + 1] = {
 45	[NFC_ATTR_DEVICE_INDEX] = { .type = NLA_U32 },
 46	[NFC_ATTR_DEVICE_NAME] = { .type = NLA_STRING,
 47				.len = NFC_DEVICE_NAME_MAXSIZE },
 48	[NFC_ATTR_PROTOCOLS] = { .type = NLA_U32 },
 49	[NFC_ATTR_COMM_MODE] = { .type = NLA_U8 },
 50	[NFC_ATTR_RF_MODE] = { .type = NLA_U8 },
 51	[NFC_ATTR_DEVICE_POWERED] = { .type = NLA_U8 },
 52};
 53
 54static int nfc_genl_send_target(struct sk_buff *msg, struct nfc_target *target,
 55				struct netlink_callback *cb, int flags)
 56{
 57	void *hdr;
 58
 
 
 59	hdr = genlmsg_put(msg, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq,
 60			  &nfc_genl_family, flags, NFC_CMD_GET_TARGET);
 61	if (!hdr)
 62		return -EMSGSIZE;
 63
 64	genl_dump_check_consistent(cb, hdr, &nfc_genl_family);
 65
 66	if (nla_put_u32(msg, NFC_ATTR_TARGET_INDEX, target->idx) ||
 67	    nla_put_u32(msg, NFC_ATTR_PROTOCOLS, target->supported_protocols) ||
 68	    nla_put_u16(msg, NFC_ATTR_TARGET_SENS_RES, target->sens_res) ||
 69	    nla_put_u8(msg, NFC_ATTR_TARGET_SEL_RES, target->sel_res))
 70		goto nla_put_failure;
 71	if (target->nfcid1_len > 0 &&
 72	    nla_put(msg, NFC_ATTR_TARGET_NFCID1, target->nfcid1_len,
 73		    target->nfcid1))
 74		goto nla_put_failure;
 75	if (target->sensb_res_len > 0 &&
 76	    nla_put(msg, NFC_ATTR_TARGET_SENSB_RES, target->sensb_res_len,
 77		    target->sensb_res))
 78		goto nla_put_failure;
 79	if (target->sensf_res_len > 0 &&
 80	    nla_put(msg, NFC_ATTR_TARGET_SENSF_RES, target->sensf_res_len,
 81		    target->sensf_res))
 82		goto nla_put_failure;
 83
 84	return genlmsg_end(msg, hdr);
 85
 86nla_put_failure:
 87	genlmsg_cancel(msg, hdr);
 88	return -EMSGSIZE;
 89}
 90
 91static struct nfc_dev *__get_device_from_cb(struct netlink_callback *cb)
 92{
 93	struct nfc_dev *dev;
 94	int rc;
 95	u32 idx;
 96
 97	rc = nlmsg_parse(cb->nlh, GENL_HDRLEN + nfc_genl_family.hdrsize,
 98			 nfc_genl_family.attrbuf,
 99			 nfc_genl_family.maxattr,
100			 nfc_genl_policy);
101	if (rc < 0)
102		return ERR_PTR(rc);
103
104	if (!nfc_genl_family.attrbuf[NFC_ATTR_DEVICE_INDEX])
105		return ERR_PTR(-EINVAL);
106
107	idx = nla_get_u32(nfc_genl_family.attrbuf[NFC_ATTR_DEVICE_INDEX]);
108
109	dev = nfc_get_device(idx);
110	if (!dev)
111		return ERR_PTR(-ENODEV);
112
113	return dev;
114}
115
116static int nfc_genl_dump_targets(struct sk_buff *skb,
117				 struct netlink_callback *cb)
118{
119	int i = cb->args[0];
120	struct nfc_dev *dev = (struct nfc_dev *) cb->args[1];
121	int rc;
122
 
 
123	if (!dev) {
124		dev = __get_device_from_cb(cb);
125		if (IS_ERR(dev))
126			return PTR_ERR(dev);
127
128		cb->args[1] = (long) dev;
129	}
130
131	device_lock(&dev->dev);
132
133	cb->seq = dev->targets_generation;
134
135	while (i < dev->n_targets) {
136		rc = nfc_genl_send_target(skb, &dev->targets[i], cb,
137					  NLM_F_MULTI);
138		if (rc < 0)
139			break;
140
141		i++;
142	}
143
144	device_unlock(&dev->dev);
145
146	cb->args[0] = i;
147
148	return skb->len;
149}
150
151static int nfc_genl_dump_targets_done(struct netlink_callback *cb)
152{
153	struct nfc_dev *dev = (struct nfc_dev *) cb->args[1];
154
 
 
155	if (dev)
156		nfc_put_device(dev);
157
158	return 0;
159}
160
161int nfc_genl_targets_found(struct nfc_dev *dev)
162{
163	struct sk_buff *msg;
164	void *hdr;
165
 
 
166	dev->genl_data.poll_req_pid = 0;
167
168	msg = nlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC);
169	if (!msg)
170		return -ENOMEM;
171
172	hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
173			  NFC_EVENT_TARGETS_FOUND);
174	if (!hdr)
175		goto free_msg;
176
177	if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx))
178		goto nla_put_failure;
179
180	genlmsg_end(msg, hdr);
181
182	return genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_ATOMIC);
183
184nla_put_failure:
185	genlmsg_cancel(msg, hdr);
186free_msg:
187	nlmsg_free(msg);
188	return -EMSGSIZE;
189}
190
191int nfc_genl_target_lost(struct nfc_dev *dev, u32 target_idx)
192{
193	struct sk_buff *msg;
194	void *hdr;
195
196	msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
197	if (!msg)
198		return -ENOMEM;
199
200	hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
201			  NFC_EVENT_TARGET_LOST);
202	if (!hdr)
203		goto free_msg;
204
205	if (nla_put_string(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev)) ||
206	    nla_put_u32(msg, NFC_ATTR_TARGET_INDEX, target_idx))
207		goto nla_put_failure;
208
209	genlmsg_end(msg, hdr);
210
211	genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_KERNEL);
212
213	return 0;
214
215nla_put_failure:
216	genlmsg_cancel(msg, hdr);
217free_msg:
218	nlmsg_free(msg);
219	return -EMSGSIZE;
220}
221
222int nfc_genl_device_added(struct nfc_dev *dev)
223{
224	struct sk_buff *msg;
225	void *hdr;
226
 
 
227	msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
228	if (!msg)
229		return -ENOMEM;
230
231	hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
232			  NFC_EVENT_DEVICE_ADDED);
233	if (!hdr)
234		goto free_msg;
235
236	if (nla_put_string(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev)) ||
237	    nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx) ||
238	    nla_put_u32(msg, NFC_ATTR_PROTOCOLS, dev->supported_protocols) ||
239	    nla_put_u8(msg, NFC_ATTR_DEVICE_POWERED, dev->dev_up))
240		goto nla_put_failure;
241
242	genlmsg_end(msg, hdr);
243
244	genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_KERNEL);
245
246	return 0;
247
248nla_put_failure:
249	genlmsg_cancel(msg, hdr);
250free_msg:
251	nlmsg_free(msg);
252	return -EMSGSIZE;
253}
254
255int nfc_genl_device_removed(struct nfc_dev *dev)
256{
257	struct sk_buff *msg;
258	void *hdr;
259
 
 
260	msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
261	if (!msg)
262		return -ENOMEM;
263
264	hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
265			  NFC_EVENT_DEVICE_REMOVED);
266	if (!hdr)
267		goto free_msg;
268
269	if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx))
270		goto nla_put_failure;
271
272	genlmsg_end(msg, hdr);
273
274	genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_KERNEL);
275
276	return 0;
277
278nla_put_failure:
279	genlmsg_cancel(msg, hdr);
280free_msg:
281	nlmsg_free(msg);
282	return -EMSGSIZE;
283}
284
285static int nfc_genl_send_device(struct sk_buff *msg, struct nfc_dev *dev,
286				u32 pid, u32 seq,
287				struct netlink_callback *cb,
288				int flags)
289{
290	void *hdr;
291
 
 
292	hdr = genlmsg_put(msg, pid, seq, &nfc_genl_family, flags,
293			  NFC_CMD_GET_DEVICE);
294	if (!hdr)
295		return -EMSGSIZE;
296
297	if (cb)
298		genl_dump_check_consistent(cb, hdr, &nfc_genl_family);
299
300	if (nla_put_string(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev)) ||
301	    nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx) ||
302	    nla_put_u32(msg, NFC_ATTR_PROTOCOLS, dev->supported_protocols) ||
303	    nla_put_u8(msg, NFC_ATTR_DEVICE_POWERED, dev->dev_up))
304		goto nla_put_failure;
305
306	return genlmsg_end(msg, hdr);
307
308nla_put_failure:
309	genlmsg_cancel(msg, hdr);
310	return -EMSGSIZE;
311}
312
313static int nfc_genl_dump_devices(struct sk_buff *skb,
314				 struct netlink_callback *cb)
315{
316	struct class_dev_iter *iter = (struct class_dev_iter *) cb->args[0];
317	struct nfc_dev *dev = (struct nfc_dev *) cb->args[1];
318	bool first_call = false;
319
 
 
320	if (!iter) {
321		first_call = true;
322		iter = kmalloc(sizeof(struct class_dev_iter), GFP_KERNEL);
323		if (!iter)
324			return -ENOMEM;
325		cb->args[0] = (long) iter;
326	}
327
328	mutex_lock(&nfc_devlist_mutex);
329
330	cb->seq = nfc_devlist_generation;
331
332	if (first_call) {
333		nfc_device_iter_init(iter);
334		dev = nfc_device_iter_next(iter);
335	}
336
337	while (dev) {
338		int rc;
339
340		rc = nfc_genl_send_device(skb, dev, NETLINK_CB(cb->skb).pid,
341					  cb->nlh->nlmsg_seq, cb, NLM_F_MULTI);
 
342		if (rc < 0)
343			break;
344
345		dev = nfc_device_iter_next(iter);
346	}
347
348	mutex_unlock(&nfc_devlist_mutex);
349
350	cb->args[1] = (long) dev;
351
352	return skb->len;
353}
354
355static int nfc_genl_dump_devices_done(struct netlink_callback *cb)
356{
357	struct class_dev_iter *iter = (struct class_dev_iter *) cb->args[0];
358
 
 
359	nfc_device_iter_exit(iter);
360	kfree(iter);
361
362	return 0;
363}
364
365int nfc_genl_dep_link_up_event(struct nfc_dev *dev, u32 target_idx,
366			       u8 comm_mode, u8 rf_mode)
367{
368	struct sk_buff *msg;
369	void *hdr;
370
371	pr_debug("DEP link is up\n");
372
373	msg = nlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC);
374	if (!msg)
375		return -ENOMEM;
376
377	hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0, NFC_CMD_DEP_LINK_UP);
378	if (!hdr)
379		goto free_msg;
380
381	if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx))
382		goto nla_put_failure;
383	if (rf_mode == NFC_RF_INITIATOR &&
384	    nla_put_u32(msg, NFC_ATTR_TARGET_INDEX, target_idx))
385		goto nla_put_failure;
386	if (nla_put_u8(msg, NFC_ATTR_COMM_MODE, comm_mode) ||
387	    nla_put_u8(msg, NFC_ATTR_RF_MODE, rf_mode))
388		goto nla_put_failure;
389
390	genlmsg_end(msg, hdr);
391
392	dev->dep_link_up = true;
393
394	genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_ATOMIC);
395
396	return 0;
397
398nla_put_failure:
399	genlmsg_cancel(msg, hdr);
400free_msg:
401	nlmsg_free(msg);
402	return -EMSGSIZE;
403}
404
405int nfc_genl_dep_link_down_event(struct nfc_dev *dev)
406{
407	struct sk_buff *msg;
408	void *hdr;
409
410	pr_debug("DEP link is down\n");
411
412	msg = nlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC);
413	if (!msg)
414		return -ENOMEM;
415
416	hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
417			  NFC_CMD_DEP_LINK_DOWN);
418	if (!hdr)
419		goto free_msg;
420
421	if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx))
422		goto nla_put_failure;
423
424	genlmsg_end(msg, hdr);
425
426	genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_ATOMIC);
427
428	return 0;
429
430nla_put_failure:
431	genlmsg_cancel(msg, hdr);
432free_msg:
433	nlmsg_free(msg);
434	return -EMSGSIZE;
435}
436
437static int nfc_genl_get_device(struct sk_buff *skb, struct genl_info *info)
438{
439	struct sk_buff *msg;
440	struct nfc_dev *dev;
441	u32 idx;
442	int rc = -ENOBUFS;
443
 
 
444	if (!info->attrs[NFC_ATTR_DEVICE_INDEX])
445		return -EINVAL;
446
447	idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
448
449	dev = nfc_get_device(idx);
450	if (!dev)
451		return -ENODEV;
452
453	msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
454	if (!msg) {
455		rc = -ENOMEM;
456		goto out_putdev;
457	}
458
459	rc = nfc_genl_send_device(msg, dev, info->snd_pid, info->snd_seq,
460				  NULL, 0);
461	if (rc < 0)
462		goto out_free;
463
464	nfc_put_device(dev);
465
466	return genlmsg_reply(msg, info);
467
468out_free:
469	nlmsg_free(msg);
470out_putdev:
471	nfc_put_device(dev);
472	return rc;
473}
474
475static int nfc_genl_dev_up(struct sk_buff *skb, struct genl_info *info)
476{
477	struct nfc_dev *dev;
478	int rc;
479	u32 idx;
480
481	if (!info->attrs[NFC_ATTR_DEVICE_INDEX])
482		return -EINVAL;
483
484	idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
485
486	dev = nfc_get_device(idx);
487	if (!dev)
488		return -ENODEV;
489
490	rc = nfc_dev_up(dev);
491
492	nfc_put_device(dev);
493	return rc;
494}
495
496static int nfc_genl_dev_down(struct sk_buff *skb, struct genl_info *info)
497{
498	struct nfc_dev *dev;
499	int rc;
500	u32 idx;
501
502	if (!info->attrs[NFC_ATTR_DEVICE_INDEX])
503		return -EINVAL;
504
505	idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
506
507	dev = nfc_get_device(idx);
508	if (!dev)
509		return -ENODEV;
510
511	rc = nfc_dev_down(dev);
512
513	nfc_put_device(dev);
514	return rc;
515}
516
517static int nfc_genl_start_poll(struct sk_buff *skb, struct genl_info *info)
518{
519	struct nfc_dev *dev;
520	int rc;
521	u32 idx;
522	u32 protocols;
523
524	pr_debug("Poll start\n");
525
526	if (!info->attrs[NFC_ATTR_DEVICE_INDEX] ||
527	    !info->attrs[NFC_ATTR_PROTOCOLS])
528		return -EINVAL;
529
530	idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
531	protocols = nla_get_u32(info->attrs[NFC_ATTR_PROTOCOLS]);
532
533	dev = nfc_get_device(idx);
534	if (!dev)
535		return -ENODEV;
536
537	mutex_lock(&dev->genl_data.genl_data_mutex);
538
539	rc = nfc_start_poll(dev, protocols);
540	if (!rc)
541		dev->genl_data.poll_req_pid = info->snd_pid;
542
543	mutex_unlock(&dev->genl_data.genl_data_mutex);
544
545	nfc_put_device(dev);
546	return rc;
547}
548
549static int nfc_genl_stop_poll(struct sk_buff *skb, struct genl_info *info)
550{
551	struct nfc_dev *dev;
552	int rc;
553	u32 idx;
554
 
 
555	if (!info->attrs[NFC_ATTR_DEVICE_INDEX])
556		return -EINVAL;
557
558	idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
559
560	dev = nfc_get_device(idx);
561	if (!dev)
562		return -ENODEV;
563
564	mutex_lock(&dev->genl_data.genl_data_mutex);
565
566	if (dev->genl_data.poll_req_pid != info->snd_pid) {
567		rc = -EBUSY;
568		goto out;
569	}
570
571	rc = nfc_stop_poll(dev);
572	dev->genl_data.poll_req_pid = 0;
573
574out:
575	mutex_unlock(&dev->genl_data.genl_data_mutex);
576	nfc_put_device(dev);
577	return rc;
578}
579
580static int nfc_genl_dep_link_up(struct sk_buff *skb, struct genl_info *info)
581{
582	struct nfc_dev *dev;
583	int rc, tgt_idx;
584	u32 idx;
585	u8 comm;
586
587	pr_debug("DEP link up\n");
588
589	if (!info->attrs[NFC_ATTR_DEVICE_INDEX] ||
590	    !info->attrs[NFC_ATTR_COMM_MODE])
591		return -EINVAL;
592
593	idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
594	if (!info->attrs[NFC_ATTR_TARGET_INDEX])
595		tgt_idx = NFC_TARGET_IDX_ANY;
596	else
597		tgt_idx = nla_get_u32(info->attrs[NFC_ATTR_TARGET_INDEX]);
598
599	comm = nla_get_u8(info->attrs[NFC_ATTR_COMM_MODE]);
600
601	if (comm != NFC_COMM_ACTIVE && comm != NFC_COMM_PASSIVE)
602		return -EINVAL;
603
604	dev = nfc_get_device(idx);
605	if (!dev)
606		return -ENODEV;
607
608	rc = nfc_dep_link_up(dev, tgt_idx, comm);
609
610	nfc_put_device(dev);
611
612	return rc;
613}
614
615static int nfc_genl_dep_link_down(struct sk_buff *skb, struct genl_info *info)
616{
617	struct nfc_dev *dev;
618	int rc;
619	u32 idx;
620
621	if (!info->attrs[NFC_ATTR_DEVICE_INDEX])
622		return -EINVAL;
623
624	idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
625
626	dev = nfc_get_device(idx);
627	if (!dev)
628		return -ENODEV;
629
630	rc = nfc_dep_link_down(dev);
631
632	nfc_put_device(dev);
633	return rc;
634}
635
636static struct genl_ops nfc_genl_ops[] = {
637	{
638		.cmd = NFC_CMD_GET_DEVICE,
639		.doit = nfc_genl_get_device,
640		.dumpit = nfc_genl_dump_devices,
641		.done = nfc_genl_dump_devices_done,
642		.policy = nfc_genl_policy,
643	},
644	{
645		.cmd = NFC_CMD_DEV_UP,
646		.doit = nfc_genl_dev_up,
647		.policy = nfc_genl_policy,
648	},
649	{
650		.cmd = NFC_CMD_DEV_DOWN,
651		.doit = nfc_genl_dev_down,
652		.policy = nfc_genl_policy,
653	},
654	{
655		.cmd = NFC_CMD_START_POLL,
656		.doit = nfc_genl_start_poll,
657		.policy = nfc_genl_policy,
658	},
659	{
660		.cmd = NFC_CMD_STOP_POLL,
661		.doit = nfc_genl_stop_poll,
662		.policy = nfc_genl_policy,
663	},
664	{
665		.cmd = NFC_CMD_DEP_LINK_UP,
666		.doit = nfc_genl_dep_link_up,
667		.policy = nfc_genl_policy,
668	},
669	{
670		.cmd = NFC_CMD_DEP_LINK_DOWN,
671		.doit = nfc_genl_dep_link_down,
672		.policy = nfc_genl_policy,
673	},
674	{
675		.cmd = NFC_CMD_GET_TARGET,
676		.dumpit = nfc_genl_dump_targets,
677		.done = nfc_genl_dump_targets_done,
678		.policy = nfc_genl_policy,
679	},
680};
681
682static int nfc_genl_rcv_nl_event(struct notifier_block *this,
683				 unsigned long event, void *ptr)
684{
685	struct netlink_notify *n = ptr;
686	struct class_dev_iter iter;
687	struct nfc_dev *dev;
688
689	if (event != NETLINK_URELEASE || n->protocol != NETLINK_GENERIC)
690		goto out;
691
692	pr_debug("NETLINK_URELEASE event from id %d\n", n->pid);
693
694	nfc_device_iter_init(&iter);
695	dev = nfc_device_iter_next(&iter);
696
697	while (dev) {
 
698		if (dev->genl_data.poll_req_pid == n->pid) {
699			nfc_stop_poll(dev);
700			dev->genl_data.poll_req_pid = 0;
701		}
 
702		dev = nfc_device_iter_next(&iter);
703	}
704
705	nfc_device_iter_exit(&iter);
706
707out:
708	return NOTIFY_DONE;
709}
710
711void nfc_genl_data_init(struct nfc_genl_data *genl_data)
712{
713	genl_data->poll_req_pid = 0;
714	mutex_init(&genl_data->genl_data_mutex);
715}
716
717void nfc_genl_data_exit(struct nfc_genl_data *genl_data)
718{
719	mutex_destroy(&genl_data->genl_data_mutex);
720}
721
722static struct notifier_block nl_notifier = {
723	.notifier_call  = nfc_genl_rcv_nl_event,
724};
725
726/**
727 * nfc_genl_init() - Initialize netlink interface
728 *
729 * This initialization function registers the nfc netlink family.
730 */
731int __init nfc_genl_init(void)
732{
733	int rc;
734
735	rc = genl_register_family_with_ops(&nfc_genl_family, nfc_genl_ops,
736					   ARRAY_SIZE(nfc_genl_ops));
737	if (rc)
738		return rc;
739
740	rc = genl_register_mc_group(&nfc_genl_family, &nfc_genl_event_mcgrp);
741
742	netlink_register_notifier(&nl_notifier);
743
744	return rc;
745}
746
747/**
748 * nfc_genl_exit() - Deinitialize netlink interface
749 *
750 * This exit function unregisters the nfc netlink family.
751 */
752void nfc_genl_exit(void)
753{
754	netlink_unregister_notifier(&nl_notifier);
755	genl_unregister_family(&nfc_genl_family);
756}
v3.1
  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
 30static struct genl_multicast_group nfc_genl_event_mcgrp = {
 31	.name = NFC_GENL_MCAST_EVENT_NAME,
 32};
 33
 34struct 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
 42static 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
 49static 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
 71nla_put_failure:
 72	genlmsg_cancel(msg, hdr);
 73	return -EMSGSIZE;
 74}
 75
 76static 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
101static 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
138static 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
150int 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
174nla_put_failure:
175	genlmsg_cancel(msg, hdr);
176free_msg:
177	nlmsg_free(msg);
178	return -EMSGSIZE;
179}
180
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
181int 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
207nla_put_failure:
208	genlmsg_cancel(msg, hdr);
209free_msg:
210	nlmsg_free(msg);
211	return -EMSGSIZE;
212}
213
214int 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
238nla_put_failure:
239	genlmsg_cancel(msg, hdr);
240free_msg:
241	nlmsg_free(msg);
242	return -EMSGSIZE;
243}
244
245static 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
268nla_put_failure:
269	genlmsg_cancel(msg, hdr);
270	return -EMSGSIZE;
271}
272
273static 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
318static 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
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
330static 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
363out_free:
364	nlmsg_free(msg);
365out_putdev:
366	nfc_put_device(dev);
367	return rc;
368}
369
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
370static 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
402static 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
429out:
430	mutex_unlock(&dev->genl_data.genl_data_mutex);
431	nfc_put_device(dev);
432	return rc;
433}
434
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
435static 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
461static 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
488out:
489	return NOTIFY_DONE;
490}
491
492void 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
498void nfc_genl_data_exit(struct nfc_genl_data *genl_data)
499{
500	mutex_destroy(&genl_data->genl_data_mutex);
501}
502
503static 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 */
512int __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 */
533void nfc_genl_exit(void)
534{
535	netlink_unregister_notifier(&nl_notifier);
536	genl_unregister_family(&nfc_genl_family);
537}