summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cleopatre/application/managerd/src/bridge.c6
-rw-r--r--cleopatre/application/managerd/src/managerd.c22
-rw-r--r--cleopatre/application/managerd/src/mme_nl.c63
-rw-r--r--cleopatre/devkit/plcd/Makefile2
-rw-r--r--cleopatre/devkit/plcd/inc/plcd.h3
-rw-r--r--cleopatre/devkit/plcd/src/plcd_main.c21
-rw-r--r--cleopatre/devkit/plcdrv/arm/src/linux_drv.c36
-rw-r--r--cleopatre/linux-2.6.25.10-spc300/include/asm-arm/arch-spc300/ioctl.h33
8 files changed, 171 insertions, 15 deletions
diff --git a/cleopatre/application/managerd/src/bridge.c b/cleopatre/application/managerd/src/bridge.c
index 3d6c13a973..a72f943088 100644
--- a/cleopatre/application/managerd/src/bridge.c
+++ b/cleopatre/application/managerd/src/bridge.c
@@ -220,9 +220,9 @@ int bridge_init(struct managerd_ctx *ctx)
//Bind LO socket to this interface
if(-1 == (bind(ctx->sock_lo, (struct sockaddr *)&sll, sizeof(struct sockaddr_ll))))
{
- syslog(LOG_WARNING, "cannot bind raw socket to interface %s (%s)", LO_IFNAME, strerror(errno));
- close(ctx->sock_lo);
- close(ctx->sock_br);
+ syslog (LOG_WARNING, "cannot bind raw socket to interface %s (%s)", LO_IFNAME, strerror (errno));
+ close (ctx->sock_br);
+ close (ctx->sock_lo);
return -1;
}
diff --git a/cleopatre/application/managerd/src/managerd.c b/cleopatre/application/managerd/src/managerd.c
index 12dda3a488..abc6e6f68b 100644
--- a/cleopatre/application/managerd/src/managerd.c
+++ b/cleopatre/application/managerd/src/managerd.c
@@ -263,16 +263,28 @@ static int managerd_init(struct managerd_ctx *ctx)
return -1;
//Initialize mme part
- if(0 > mme_nl_init(ctx))
+ if (0 > mme_nl_init (ctx))
+ {
+ bridge_uninit (ctx);
return -1;
+ }
//Initialize simple connect part (open "/dev/gpio")
- if(0 > simple_connect_init(ctx))
+ if (0 > simple_connect_init (ctx))
+ {
+ bridge_uninit (ctx);
+ mme_nl_uninit (ctx);
return -1;
+ }
/* Initialize led part (need "/dev/gpio") */
if (0 > led_init (ctx))
+ {
+ bridge_uninit (ctx);
+ mme_nl_uninit (ctx);
+ simple_connect_uninit (ctx);
return -1;
+ }
/* Set default values of hpav.info file into managerd context */
strcpy (ctx->hpav_info.status, LIBSPID_HPAV_INFO_VALUE_STATUS_UNASSOCIATED);
@@ -290,7 +302,11 @@ static int managerd_init(struct managerd_ctx *ctx)
LIBSPID_HPAV_INFO_PATH, managerd_signal_handler))
{
syslog (LOG_WARNING, "libspid system file update register failed");
- return -1;
+ bridge_uninit (ctx);
+ mme_nl_uninit (ctx);
+ led_uninit (ctx);
+ simple_connect_uninit (ctx);
+ return -1;
}
return 0;
diff --git a/cleopatre/application/managerd/src/mme_nl.c b/cleopatre/application/managerd/src/mme_nl.c
index 07b38dd1e5..f089c18d62 100644
--- a/cleopatre/application/managerd/src/mme_nl.c
+++ b/cleopatre/application/managerd/src/mme_nl.c
@@ -36,8 +36,12 @@
#include <asm/byteorder.h>
#include <linux/netlink.h>
+#include "ioctl.h"
+
#include "mme_nl.h"
+#define PLC_IFNAME "plc0"
+
/**
* Receive a frame from MME interface.
*
@@ -145,8 +149,10 @@ int mme_nl_send(struct managerd_ctx *ctx, uint8_t *buffer, int len)
*/
int mme_nl_init(struct managerd_ctx *ctx)
{
- struct sockaddr_ll sll;
- struct ifreq ifr;
+ struct plcdrv_setpid user_data = {0};
+ struct ifreq ifr = {0};
+ int sock_plc;
+ struct sockaddr_ll plc_sll;
//Check arguments
assert(ctx != NULL);
@@ -163,9 +169,60 @@ int mme_nl_init(struct managerd_ctx *ctx)
ctx->mme_snl.nl_groups = 0; /* not in mcast group */
if (0 > bind(ctx->sock_mme, (struct sockaddr *)&ctx->mme_snl, sizeof(ctx->mme_snl)))
{
- syslog (LOG_WARNING, "cannot bind socket on %s (%s)", MME_IFNAME, strerror(errno));
+ syslog (LOG_WARNING, "cannot bind socket on %s (%s)", MME_IFNAME, strerror (errno));
+ close (ctx->sock_mme);
+ return -1;
+ }
+
+ /* Create a receive connection on PLC interface */
+ if (0 > (sock_plc = socket (AF_PACKET, SOCK_RAW, ETH_P_HPAV)))
+ {
+ syslog (LOG_WARNING, "cannot open socket on %s (%s)", PLC_IFNAME,
+ strerror (errno));
+ close (ctx->sock_mme);
+ return -1;
+ }
+
+ /* Prepare PLC socket address */
+ strncpy (ifr.ifr_name, (char*) PLC_IFNAME, IFNAMSIZ);
+ if (-1 == (ioctl (sock_plc, SIOCGIFINDEX, &ifr)))
+ {
+ syslog (LOG_WARNING, "cannot get interface %s index (%s)",
+ PLC_IFNAME, strerror (errno));
+ close (ctx->sock_mme);
+ close (sock_plc);
return -1;
}
+ plc_sll.sll_family = AF_PACKET;
+ plc_sll.sll_ifindex = ifr.ifr_ifindex;
+ plc_sll.sll_protocol = htons (ETH_P_HPAV);
+
+ /* Bind PLC socket to this interface */
+ if (-1 == (bind (sock_plc, (struct sockaddr *) &plc_sll,
+ sizeof (struct sockaddr_ll))))
+ {
+ syslog (LOG_WARNING, "cannot bind raw socket to interface %s (%s)",
+ PLC_IFNAME, strerror (errno));
+ close (ctx->sock_mme);
+ close (sock_plc);
+ return -1;
+ }
+
+ /* Set managerd pid for reception on mme netlink */
+ user_data.nl = NETLINK_PLC_MME;
+ user_data.pid = getpid ();
+ ifr.ifr_data = (void *) &user_data;
+ strncpy (ifr.ifr_name, (char*) PLC_IFNAME, IFNAMSIZ);
+ if (0 > (ioctl (sock_plc, PLCDRV_IOCTL_SETPID, &ifr)))
+ {
+ syslog (LOG_WARNING, "cannot call ioctl SETPID (%s)", strerror (errno));
+ close (ctx->sock_mme);
+ close (sock_plc);
+ return -1;
+ }
+
+ /* We do not need PLC connection anymore => close it. */
+ close (sock_plc);
return 0;
}
diff --git a/cleopatre/devkit/plcd/Makefile b/cleopatre/devkit/plcd/Makefile
index 3f6caf028e..116691d883 100644
--- a/cleopatre/devkit/plcd/Makefile
+++ b/cleopatre/devkit/plcd/Makefile
@@ -10,7 +10,7 @@ LINUX_DIR=../../linux-2.6.25.10-spc300
VERSION=$(shell git describe --always 2>/dev/null)
INC=-I$(INCPATH) -I$(LIBMME_DIR)/inc -I$(LIBSPID_DIR)/inc -I../../include \
- -I$(LINUX_DIR)/include
+ -I$(LINUX_DIR)/include -I$(LINUX_DIR)/include/asm-arm/arch-spc300
CC=arm-linux-gcc
CFLAGS+= $(INC) -Os -MMD -DVERSION=\"$(VERSION)\"
diff --git a/cleopatre/devkit/plcd/inc/plcd.h b/cleopatre/devkit/plcd/inc/plcd.h
index d21e9bc8b6..d8830c8d5d 100644
--- a/cleopatre/devkit/plcd/inc/plcd.h
+++ b/cleopatre/devkit/plcd/inc/plcd.h
@@ -62,6 +62,9 @@
#define PLCD_EVENT_REFRESH_TIMEOUT_MS 1000
#define PLCD_INIT_RETRIES 10
+/* Interface name */
+#define PLC_IFNAME "plc0"
+
typedef enum
{
MME_DRV_STATUS_ASSOC_UNASSOCIATED = 0,
diff --git a/cleopatre/devkit/plcd/src/plcd_main.c b/cleopatre/devkit/plcd/src/plcd_main.c
index 3acd59f929..eb7248f457 100644
--- a/cleopatre/devkit/plcd/src/plcd_main.c
+++ b/cleopatre/devkit/plcd/src/plcd_main.c
@@ -23,6 +23,11 @@
#include <syslog.h>
#include <sys/types.h>
#include <unistd.h> /* for getpid() */
+#include <net/if.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+
+#include "ioctl.h"
#include "libmme.h"
#include "libspid.h"
@@ -32,7 +37,6 @@
# include "plcd_utests.h"
#endif /* __UTESTS__ */
-
static spc300_nvram_t g_nvram;
volatile sig_atomic_t is_process_signal_needed;
@@ -93,6 +97,9 @@ plcd_init (plcd_ctx_t *ctx)
{
char is_cco_preferred_str[LIBSPID_BOOLEAN_STR_MAX_LEN] = {0};
char was_cco_str[LIBSPID_BOOLEAN_STR_MAX_LEN] = {0};
+ struct plcdrv_setpid user_data = {0};
+ struct ifreq ifr = {0};
+ pid_t pid = getpid ();
PLCD_ASSERT (NULL != ctx);
@@ -133,7 +140,7 @@ plcd_init (plcd_ctx_t *ctx)
}
memset (&ctx->plcd_addr, 0, sizeof (ctx->plcd_addr));
ctx->plcd_addr.nl_family = AF_NETLINK;
- ctx->plcd_addr.nl_pid = getpid(); /* self pid */
+ ctx->plcd_addr.nl_pid = pid; /* self pid */
ctx->plcd_addr.nl_groups = 0; /* not in mcast group */
if (0 > bind (ctx->plc_sock, (struct sockaddr *) &ctx->plcd_addr,
sizeof (ctx->plcd_addr)))
@@ -142,6 +149,16 @@ plcd_init (plcd_ctx_t *ctx)
return -1;
}
+ /* Set plcd pid for reception on drv netlink */
+ user_data.nl = NETLINK_PLC_DRV;
+ user_data.pid = pid;
+ ifr.ifr_data = (void *) &user_data;
+ strncpy (ifr.ifr_name, (char*) PLC_IFNAME, IFNAMSIZ);
+ if (0 > (ioctl (ctx->plc_sock, PLCDRV_IOCTL_SETPID, &ifr)))
+ {
+ syslog (LOG_WARNING, "cannot call ioctl SETPID (%s)", strerror (errno));
+ }
+
/* get NVRAM data */
ctx->nvram = &g_nvram;
#ifdef __UTESTS__
diff --git a/cleopatre/devkit/plcdrv/arm/src/linux_drv.c b/cleopatre/devkit/plcdrv/arm/src/linux_drv.c
index 72fbeacbe2..ceeb58cd41 100644
--- a/cleopatre/devkit/plcdrv/arm/src/linux_drv.c
+++ b/cleopatre/devkit/plcdrv/arm/src/linux_drv.c
@@ -44,6 +44,7 @@
#include <asm/arch/nvram.h>
#include <asm/arch/hardware/spi.h>
#include <asm/arch/hardware/regbank.h>
+#include <asm-arm/arch-spc300/ioctl.h>
#include "boot_params.h"
#include "common.h"
@@ -1225,7 +1226,6 @@ void plcdrv_netlink_drv_tx (struct sk_buff *nlskb)
if(NULL == nlskb)
return;
nlh = nlmsg_hdr(nlskb);
- priv->nl_drv_pid = nlh->nlmsg_pid;
plcdrv_netlink_tx(nlskb, plcdrv_device, priv->nl_drv_sock);
}
@@ -1241,7 +1241,6 @@ void plcdrv_netlink_mme_tx (struct sk_buff *nlskb)
if(NULL == nlskb)
return;
nlh = nlmsg_hdr(nlskb);
- priv->nl_mme_pid = nlh->nlmsg_pid;
plcdrv_netlink_tx(nlskb, plcdrv_device, priv->nl_mme_sock);
}
@@ -1462,6 +1461,9 @@ int plcdrv_set_mac_address(struct net_device *dev, void *p)
*/
int plcdrv_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
+ struct net_priv *priv = NULL;
+ struct plcdrv_setpid user_data = {0};
+
//Check pointers
if(ifr == NULL)
return -1;
@@ -1473,7 +1475,35 @@ int plcdrv_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
//Find the command
switch(cmd)
{
- default:
+ case PLCDRV_IOCTL_SETPID:
+
+ /* Check validity of driver private data */
+ if (NULL == (priv = (struct net_priv *) dev->priv))
+ return -EFAULT;
+
+ /* Get user data */
+ if (copy_from_user (&user_data, ifr->ifr_data, sizeof (user_data)))
+ return -EFAULT;
+
+ /* During initialization, plcd & managerd register their pid
+ * for reception on drv & mme netlink */
+ if (NETLINK_PLC_DRV == user_data.nl)
+ {
+ priv->nl_drv_pid = user_data.pid;
+ printk (KERN_INFO "%s: plcd registered with pid %d\n", __FUNCTION__,
+ priv->nl_drv_pid);
+ }
+ if (NETLINK_PLC_MME == user_data.nl)
+ {
+ priv->nl_mme_pid = user_data.pid;
+ printk (KERN_INFO "%s: managerd registered with pid %d\n", __FUNCTION__,
+ priv->nl_mme_pid);
+ }
+
+ /* In case of another netlink, do nothing */
+ break;
+
+ default:
return -EOPNOTSUPP;
}
diff --git a/cleopatre/linux-2.6.25.10-spc300/include/asm-arm/arch-spc300/ioctl.h b/cleopatre/linux-2.6.25.10-spc300/include/asm-arm/arch-spc300/ioctl.h
new file mode 100644
index 0000000000..ba765d06b3
--- /dev/null
+++ b/cleopatre/linux-2.6.25.10-spc300/include/asm-arm/arch-spc300/ioctl.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2011 SPiDCOM Technologies
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef _ARCH_ARM_SPC300_IOCTL_H
+#define _ARCH_ARM_SPC300_IOCTL_H
+
+#include <asm/ioctl.h>
+
+/** IOCTL common definitions */
+
+#define PLCDRV_IOCTL_SETPID (SIOCDEVPRIVATE + 0)
+
+struct plcdrv_setpid
+{
+ int nl; /* Netlink to consider for pid registration */
+ int pid; /* Identifier of the process to register for reception */
+};
+
+#endif /* _ARCH_ARM_SPC300_IOCTL_H */