linux/samples/connector/cn_test.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * 	cn_test.c
 * 
 * 2004+ Copyright (c) Evgeniy Polyakov <[email protected]>
 * All rights reserved.
 */

#define pr_fmt(fmt)

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/skbuff.h>
#include <linux/slab.h>
#include <linux/timer.h>

#include <linux/connector.h>

static struct cb_id cn_test_id =;
static char cn_test_name[] =;
static struct sock *nls;
static struct timer_list cn_test_timer;

static void cn_test_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
{}

/*
 * Do not remove this function even if no one is using it as
 * this is an example of how to get notifications about new
 * connector user registration
 */
#if 0
static int cn_test_want_notify(void)
{
	struct cn_ctl_msg *ctl;
	struct cn_notify_req *req;
	struct cn_msg *msg = NULL;
	int size, size0;
	struct sk_buff *skb;
	struct nlmsghdr *nlh;
	u32 group = 1;

	size0 = sizeof(*msg) + sizeof(*ctl) + 3 * sizeof(*req);

	size = NLMSG_SPACE(size0);

	skb = alloc_skb(size, GFP_ATOMIC);
	if (!skb) {
		pr_err("failed to allocate new skb with size=%u\n", size);
		return -ENOMEM;
	}

	nlh = nlmsg_put(skb, 0, 0x123, NLMSG_DONE, size - sizeof(*nlh), 0);
	if (!nlh) {
		kfree_skb(skb);
		return -EMSGSIZE;
	}

	msg = nlmsg_data(nlh);

	memset(msg, 0, size0);

	msg->id.idx = -1;
	msg->id.val = -1;
	msg->seq = 0x123;
	msg->ack = 0x345;
	msg->len = size0 - sizeof(*msg);

	ctl = (struct cn_ctl_msg *)(msg + 1);

	ctl->idx_notify_num = 1;
	ctl->val_notify_num = 2;
	ctl->group = group;
	ctl->len = msg->len - sizeof(*ctl);

	req = (struct cn_notify_req *)(ctl + 1);

	/*
	 * Idx.
	 */
	req->first = cn_test_id.idx;
	req->range = 10;

	/*
	 * Val 0.
	 */
	req++;
	req->first = cn_test_id.val;
	req->range = 10;

	/*
	 * Val 1.
	 */
	req++;
	req->first = cn_test_id.val + 20;
	req->range = 10;

	NETLINK_CB(skb).dst_group = ctl->group;
	//netlink_broadcast(nls, skb, 0, ctl->group, GFP_ATOMIC);
	netlink_unicast(nls, skb, 0, 0);

	pr_info("request was sent: group=0x%x\n", ctl->group);

	return 0;
}
#endif

static u32 cn_test_timer_counter;
static void cn_test_timer_func(struct timer_list *unused)
{}

static int cn_test_init(void)
{}

static void cn_test_fini(void)
{}

module_init(cn_test_init);
module_exit(cn_test_fini);

MODULE_LICENSE();
MODULE_AUTHOR();
MODULE_DESCRIPTION();