public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: "Libor Vanek" <libor.vanek@gmail.com>
To: "Evgeniy Polyakov" <johnpol@2ka.mipt.ru>
Cc: LKML <linux-kernel@vger.kernel.org>
Subject: Re: Connector - how to start?
Date: Thu, 20 Apr 2006 17:12:33 +0200	[thread overview]
Message-ID: <369a7ef40604200812x594a8b3dxc4d730cdbfda720e@mail.gmail.com> (raw)
In-Reply-To: <20060419121423.GA6057@2ka.mipt.ru>

[-- Attachment #1: Type: text/plain, Size: 582 bytes --]

Hi,
I got it all finally everything working with "setsockopt" as suggested.

In case anybody else wants to experiment with connector, I attach my
examples (maybe add it to Documentation/connector/?)

Anyway - there are two more issues (not bugs) which I'd like to solve:
- When sending message from kernel, cn_netlink_send returns an error
in case when there is no reciever - BUT user space "send" doesn't
return an error when there is no reciever in kernel :-(

- How (if) can I do ACK (acknoledge received and processed message)?

Thanks for your help,
Libor Vanek

[-- Attachment #2: cn_recv.c --]
[-- Type: text/x-csrc, Size: 1035 bytes --]

/*
 * 	cn_recv.c
 */

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

#include <linux/connector.h>

static struct cb_id cn_recv_id = { 0x3, 0x1 };
static char cn_recv_name[] = "cn_recv";

void cn_recv_callback(void *data)
{
	struct cn_msg *msg = (struct cn_msg *)data;
	
	printk("%s: %lu: idx=%x, val=%x, seq=%u, ack=%u, len=%d: %s\n",
	       __func__, jiffies, msg->id.idx, msg->id.val,
	       msg->seq, msg->ack, msg->len, (char *)msg->data);
}

static int cn_recv_init(void)
{
	int err;

	err = cn_add_callback(&cn_recv_id, cn_recv_name, cn_recv_callback);

	printk(KERN_INFO "cn_recv loaded, cn_add_callback retval: %i\n", err);
	return 0;
}

static void cn_recv_fini(void)
{
	cn_del_callback(&cn_recv_id);
	printk(KERN_INFO "cn_recv unloaded\n");
}

module_init(cn_recv_init);
module_exit(cn_recv_fini);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Libor Vanek <libor.vanek@gmail.com>");
MODULE_DESCRIPTION("Connector's test recieve module");





[-- Attachment #3: cn_send.c --]
[-- Type: text/x-csrc, Size: 1104 bytes --]

/*
 * 	cn_send.c
 */

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

#include <linux/connector.h>

static struct cb_id cn_send_id = { 0x3, 0x1 };
static int seq_id = 0;

void my_send_test(void)
{
	struct cn_msg *msg;
	char data[32];
	int ret;
	
	msg = kmalloc(sizeof(*msg) + sizeof(data), GFP_ATOMIC);
	memset(msg, 0, sizeof(*msg) + sizeof(data));

	msg->id.idx = cn_send_id.idx;
	msg->id.val = cn_send_id.val;
	msg->ack = 0;
	msg->seq = seq_id++;
	msg->len = 5;

	msg->len = sizeof(data);
	msg->len = scnprintf(data, sizeof(data), "Ping") + 1;
	memcpy(msg + 1, data, msg->len);

	ret = cn_netlink_send(msg, cn_send_id.idx, gfp_any());
	kfree(msg);
	printk("Sent, retval: %i\n", ret);
}

static int cn_send_init(void)
{
	my_send_test();
	return 0;
}

static void cn_send_fini(void)
{
	printk(KERN_INFO "cn_send unloaded\n");
}

module_init(cn_send_init);
module_exit(cn_send_fini);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Libor Vanek <libor.vanek@gmail.com>");
MODULE_DESCRIPTION("Connector's test send module");





[-- Attachment #4: cn_user_recv.c --]
[-- Type: text/x-csrc, Size: 2014 bytes --]

/*
 * 	cn_user_recv.c
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <time.h>

#include <endian.h>
#include <asm/types.h>

#include <sys/socket.h>
#include <sys/poll.h>
#include <sys/types.h>
#include <sys/socket.h>

#include <linux/connector.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>

void process_msg(int s, struct cn_msg *msg)
{
	fprintf(stdout, "Message: %08x.%08x, len=%u, seq=%u, ack=%u, len=%u %s\n",
		msg->id.idx, msg->id.val, msg->len, msg->seq, msg->ack, msg->len, (void *)msg->data);
}

int main(int argc, char *argv[])
{
	int s;
	unsigned char buf[1024];
	int len, need_exit;

	struct sockaddr_nl l_local;
	struct cn_msg *msg;
	struct pollfd pfd;
	struct nlmsghdr *reply;
	
	memset(buf, 0, sizeof(buf));
	
	s = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);
	if (s == -1) {
		perror("socket");
		return -1;
	}
	
	l_local.nl_family = AF_NETLINK;
	l_local.nl_groups = 0x3;
	l_local.nl_pid    = getpid();
	
	if (bind(s, (struct sockaddr *)&l_local, sizeof(struct sockaddr_nl)) == -1) {
		perror("bind");
		close(s);
		return -1;
	}
	int on = l_local.nl_groups;
	if (setsockopt(s, 270, 1, &on, sizeof(on))) {
		perror("setsockopt");
		close(s);
		return -1;
	}

	pfd.fd = s;

	need_exit = 0;
	while (!need_exit) {
		pfd.events = POLLIN;
		pfd.revents = 0;
		switch (poll(&pfd, 1, -1)) {
			case 0:
				need_exit = 1;
				break;
			case -1:
				if (errno != EINTR) {
					need_exit = 1;
					break;
				}
				continue;
			default:
				break;
		}
		if (need_exit)
			break;

		len = recv(s, buf, sizeof(buf), 0);
		if (len == -1) {
			perror("recv buf");
			close(s);
			return -1;
		}

		reply = (struct nlmsghdr *)buf;

		switch (reply->nlmsg_type) {
			case NLMSG_ERROR:
				fprintf(stdout, "Error message received.\n");
				fflush(stdout);
				break;
			case NLMSG_DONE:
				msg = (struct cn_msg *)NLMSG_DATA(reply);
				process_msg(s, msg);
				break;
			default:
				break;
		}
		
	}
	
	close(s);
	return 0;
}






[-- Attachment #5: cn_user_send.c --]
[-- Type: text/x-csrc, Size: 1942 bytes --]

/*
 * 	cn_user_send.c
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <time.h>

#include <endian.h>
#include <asm/types.h>

#include <sys/socket.h>
#include <sys/poll.h>
#include <sys/types.h>
#include <sys/socket.h>

#include <linux/connector.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>

#define GROUP	0x3

static int send_seq;

static int send_cmd(int s)
{
	static char txtmsg[] = "Ping pong";
	void *m;
	struct cn_msg *cmsg;
	struct nlmsghdr *nlh;
	int size, err;
	
	size = NLMSG_SPACE(sizeof(struct cn_msg) + sizeof(txtmsg));

	nlh = malloc(size);
	if (!nlh)
		return -ENOMEM;
	
	memset(nlh, 0, size);
	
	nlh->nlmsg_seq = send_seq++;
	nlh->nlmsg_pid = getpid();
	nlh->nlmsg_type = NLMSG_DONE;
	nlh->nlmsg_len = NLMSG_LENGTH(size - sizeof(struct nlmsghdr));
	nlh->nlmsg_flags = 0;

	cmsg = NLMSG_DATA(nlh);
	
	cmsg->id.idx = GROUP;
	cmsg->id.val = 0x1;
	cmsg->seq = nlh->nlmsg_seq;
	cmsg->ack = 0;
	cmsg->len = sizeof(txtmsg);

	m = (void *)(cmsg + 1);
	memcpy(m, (void *)txtmsg, sizeof(txtmsg));
	
	err = send(s, nlh, size, 0);
	if (err == -1) {
		fprintf(stdout, "Failed to send: %s [%d].\n", strerror(errno), errno);
	}
	free(nlh);

	return err;
}

int main(int argc, char *argv[])
{
	int s;
	unsigned char buf[1024];
	int len;

	send_seq = 0;

	struct sockaddr_nl l_local;
	struct cn_msg *msg;
	struct nlmsghdr *reply;
	
	memset(buf, 0, sizeof(buf));
	
	s = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);
	if (s == -1) {
		perror("socket");
		return -1;
	}
	
	l_local.nl_family = AF_NETLINK;
	l_local.nl_groups = GROUP;
	l_local.nl_pid    = getpid();
	
	if (bind(s, (struct sockaddr *)&l_local, sizeof(struct sockaddr_nl)) == -1) {
		perror("bind");
		close(s);
		return -1;
	}
	int on = l_local.nl_groups;
	if (setsockopt(s, 270, 1, &on, sizeof(on))) {
		perror("setseckopt");
		close(s);
		return -1;
	}

	send_cmd(s);
	
	close(s);
	return 0;
}






  reply	other threads:[~2006-04-20 15:12 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-04-15  1:09 Connector - how to start? Libor Vanek
2006-04-15  2:26 ` Randy.Dunlap
2006-04-15  3:07   ` Matt Helsley
2006-04-15  9:18     ` Evgeniy Polyakov
     [not found]       ` <369a7ef40604150350x8e7dea1sbf1f83cb800dd1c3@mail.gmail.com>
2006-04-15 11:14         ` Evgeniy Polyakov
2006-04-15 12:18           ` Paul Collins
2006-04-15 12:38             ` Evgeniy Polyakov
     [not found]               ` <369a7ef40604150624n28da8895if158a2c13cac2b9e@mail.gmail.com>
2006-04-16  7:53                 ` Evgeniy Polyakov
2006-04-16 17:09                   ` Evgeniy Polyakov
     [not found]       ` <369a7ef40604160426s301dcd52r4c9826698d3d2f79@mail.gmail.com>
2006-04-16 11:40         ` Evgeniy Polyakov
     [not found]           ` <369a7ef40604160509xcf2caadi782b90da956639d5@mail.gmail.com>
2006-04-16 13:25             ` Evgeniy Polyakov
     [not found]               ` <369a7ef40604160632t16f6aab9u687a6b359997d7ea@mail.gmail.com>
2006-04-16 14:19                 ` Evgeniy Polyakov
2006-04-18  6:07                 ` Evgeniy Polyakov
     [not found]                   ` <369a7ef40604190439v6e8f1bf6lf52cfab5af3a93af@mail.gmail.com>
2006-04-19 12:14                     ` Evgeniy Polyakov
2006-04-20 15:12                       ` Libor Vanek [this message]
2006-04-20 15:25                         ` Evgeniy Polyakov
2006-04-20 15:32                           ` Libor Vanek
2006-04-15 21:48 ` Jon Masters

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=369a7ef40604200812x594a8b3dxc4d730cdbfda720e@mail.gmail.com \
    --to=libor.vanek@gmail.com \
    --cc=johnpol@2ka.mipt.ru \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox