Commit 7a7db312 authored by julien.delange's avatar julien.delange
Browse files

add rtems/ne2000 driver

 clean driver/sockets code



git-svn-id: https://tecsw.estec.esa.int/svn/taste/trunk/po-hi-c@749 129961e7-ef38-4bb5-a8f7-c9a525a55882
parent 438ed23b
......@@ -13,7 +13,7 @@
#if (defined (__PO_HI_NEED_DRIVER_SOCKETS) \
|| defined (__PO_HI_NEED_DRIVER_QEMU_NE2000_SOCKETS))
|| defined (__PO_HI_NEED_DRIVER_RTEMS_NE2000_SOCKETS))
#include <po_hi_transport.h>
......@@ -35,7 +35,11 @@ void* __po_hi_sockets_receiver_task (void);
*/
void* __po_hi_sockets_poller (void);
/*
* Generic poller for PO-HI-C protocol.
*/
void __po_hi_driver_sockets_init (__po_hi_device_id id);
#endif
#endif
......
......@@ -18,9 +18,8 @@
#include <po_hi_messages.h>
int __po_hi_driver_sockets_asn1_send (__po_hi_entity_t from,
__po_hi_entity_t to,
__po_hi_msg_t* msg);
int __po_hi_driver_sockets_asn1_send (__po_hi_task_id task_id,
__po_hi_port_t port);
void* __po_hi_sockets_asn1_poller (void);
......
......@@ -18,8 +18,8 @@ typedef char* __po_hi_inetaddr_t;
#if (defined (__PO_HI_NEED_DRIVER_SOCKETS) \
|| defined (__PO_HI_NEED_DRIVER_SOCKETS_ASN1) \
|| defined (__PO_HI_NEED_DRIVER_QEMU_NE2000_SOCKETS))
|| defined (__PO_HI_NEED_DRIVER_SOCKETS_ASN1) \
|| defined (__PO_HI_NEED_DRIVER_RTEMS_NE2000_SOCKETS))
#define __PO_HI_NOPORT 1
#define __PO_HI_NOADDR ""
......@@ -42,11 +42,7 @@ extern __po_hi_node_t mynode;
* that receives data from a socket (receiver task)
*/
void __po_hi_sockets_init (__po_hi_device_id id);
/*
* Initialize sockets, create the receiver tasks
* and sender file descriptors
*/
void __po_hi_driver_sockets_common_generic_init (__po_hi_device_id id, void* (*poller) (void));
#endif /* __PO_HI_DRIVER_SOCKETS_COMMON_H__ */
......
......@@ -48,70 +48,31 @@
#endif
#define CONFIGURE_POSIX_INIT_THREAD_TABLE
#define CONFIGURE_USE_IMFS_AS_BASE_FILESYSTEM
// #include <po_hi_rtemsconfig.h>
#include <rtems/confdefs.h>
#endif /* RTEMS_POSIX */
#if defined (X86_RTEMS)
#include <rtems/rtems_bsdnet.h>
#include <bsp.h>
/*
* Loopback interface
*/
int rtems_bsdnet_loopattach(struct rtems_bsdnet_ifconfig*, int);
static struct rtems_bsdnet_ifconfig loopback_config = {
"lo0", /* name */
rtems_bsdnet_loopattach, /* attach function */
NULL, /* link to next interface */
"127.0.0.1", /* IP address */
"255.0.0.0", /* IP net mask */
};
/*
* Default network interface
*/
static struct rtems_bsdnet_ifconfig loopback_config =
{"lo0", rtems_bsdnet_loopattach, NULL, "127.0.0.1", "255.0.0.0", };
#undef RTEMS_BSP_NETWORK_DRIVER_NAME
#undef RTEMS_BSP_NETWORK_DRIVER_ATTACH
#define RTEMS_BSP_NETWORK_DRIVER_NAME "ne1"
#define RTEMS_BSP_NETWORK_DRIVER_ATTACH rtems_ne_driver_attach
struct rtems_bsdnet_ifconfig netdriver_config =
{RTEMS_BSP_NETWORK_DRIVER_NAME,RTEMS_BSP_NETWORK_DRIVER_ATTACH,
&loopback_config,"192.168.0.1","255.255.255.0",
(char[]){ 0x00, 0x1F, 0xC6, 0xBF, 0x74, 0x06},
0,0,0,0,0,9};
struct rtems_bsdnet_ifconfig netdriver_config = {
RTEMS_BSP_NETWORK_DRIVER_NAME, /* name */
RTEMS_BSP_NETWORK_DRIVER_ATTACH, /* attach function */
&loopback_config, /* link to next interface */
"10.0.2.5", /* IP address */
"255.255.255.0", /* IP net mask */
NULL, /* Driver supplies hardware address */
0, /* Use default driver parameters */
0, /* mtu */
0, /* rbuf_count */
0, /* xbuf_count */
0, /* port */
9 /* irq */
};
/*
* Network configuration
*/
struct rtems_bsdnet_config rtems_bsdnet_config = {
&netdriver_config,
NULL,
0, /* Default network task priority */
256 * 1024, /* Default mbuf capacity */
256 * 1024, /* Default mbuf cluster capacity */
};
#endif /*(defined (X86_RTEMS) && defined (NEED_TRANSPORT)) */
struct rtems_bsdnet_config rtems_bsdnet_config =
{&netdriver_config,NULL,0,256 * 1024,256 * 1024,};
#endif /*(defined (X86_RTEMS) */
#endif /* __COMMON_H__ */
......@@ -83,6 +83,7 @@ ifeq ($(NEED_TRANSPORT), yes)
drivers/po_hi_driver_sockets.o \
drivers/po_hi_driver_sockets_common.o \
drivers/po_hi_driver_sockets_asn1.o \
drivers/po_hi_driver_rtems_ne2000.o \
drivers/po_hi_driver_rasta_serial.o \
drivers/po_hi_driver_rasta_1553.o \
drivers/po_hi_driver_rasta_1553_brmlib.o \
......
......@@ -4,6 +4,7 @@ C_FILES = $(srcdir)/po_hi_driver_linux_serial.c \
$(srcdir)/po_hi_driver_sockets.c \
$(srcdir)/po_hi_driver_sockets_common.c \
$(srcdir)/po_hi_driver_sockets_asn1.c \
$(srcdir)/po_hi_driver_rtems_ne2000.c \
$(srcdir)/po_hi_driver_rasta_spacewire.c \
$(srcdir)/po_hi_driver_rasta_1553.c \
$(srcdir)/po_hi_driver_rasta_1553_brmlib.c \
......
#include <deployment.h>
#ifdef __PO_HI_NEED_DRIVER_RTEMS_NE2000_SOCKETS
#include <bsp.h>
#include <rtems/rtems_bsdnet.h>
#include <po_hi_transport.h>
#include <po_hi_debug.h>
#include <drivers/po_hi_driver_sockets.h>
extern __po_hi_device_id socket_device_id;
extern struct rtems_bsdnet_ifconfig netdriver_config;
char __po_hi_rtems_ethernet_address[6] = { 0x00, 0x1F, 0xC6, 0xBF, 0x74, 0x06};
extern __po_hi_inetnode_t nodes[__PO_HI_NB_DEVICES];
extern __po_hi_inetnode_t rnodes[__PO_HI_NB_DEVICES];
void __po_hi_driver_rtems_ne2000_init (__po_hi_device_id id)
{
char* dev_conf;
char dev_addr[16];
int dev_port;
int node;
memset (dev_addr, '\0', 16);
for (node = 0 ; node < __PO_HI_NB_DEVICES ; node++)
{
nodes[node].socket = -1;
}
dev_conf = __po_hi_get_device_naming (id);
dev_port = 0;
if (sscanf (dev_conf, "ip %s %d", dev_addr, &dev_port) == 0)
{
__DEBUGMSG ("[DRIVER SOCKETS] Unable to parse device configuration (id=%d)\n", id);
}
__DEBUGMSG ("My configuration, addr=%s, port=%d\n", dev_addr, dev_port);
memset (netdriver_config.ip_address, '\0', 15);
memcpy (netdriver_config.ip_address, dev_addr, strlen (dev_addr));
memcpy (netdriver_config.ip_netmask, "255.255.255.0", 13);
__DEBUGMSG ("Set configuration addr for RTEMS=%s\n", netdriver_config.ip_address);
__po_hi_rtems_ethernet_address[5] = (dev_port + 23) % 254;
netdriver_config.hardware_address = __po_hi_rtems_ethernet_address;
__DEBUGMSG ("Init RTEMS\n");
if (rtems_bsdnet_initialize_network () != RTEMS_SUCCESSFUL)
{
__DEBUGMSG ("Error when initializing RTEMS network\n");
return;
}
__DEBUGMSG ("RTEMS network init done\n");
#ifdef __PO_HI_DEBUG
rtems_bsdnet_show_if_stats ();
#endif
__po_hi_driver_sockets_common_generic_init (id, __po_hi_sockets_poller);
}
#endif
......@@ -12,7 +12,8 @@
#include <deployment.h>
#include <marshallers.h>
#if (defined (__PO_HI_NEED_DRIVER_SOCKETS) || defined (__PO_HI_NEED_DRIVER_QEMU_NE2000_SOCKETS))
#if (defined (__PO_HI_NEED_DRIVER_SOCKETS) || \
defined (__PO_HI_NEED_DRIVER_RTEMS_NE2000_SOCKETS))
#include <po_hi_config.h>
#include <po_hi_task.h>
......@@ -25,10 +26,6 @@
#include <po_hi_task.h>
#include <drivers/po_hi_driver_sockets.h>
#ifdef __PO_HI_USE_GIOP
#include <po_hi_giop.h>
#endif
#include <activity.h>
#include <signal.h>
......@@ -68,8 +65,14 @@
* listen socket. This array is used only by the receiver_task
*/
#ifdef __PO_HI_NEED_DRIVER_SOCKETS
__po_hi_inetnode_t nodes[__PO_HI_NB_NODES];
__po_hi_inetnode_t rnodes[__PO_HI_NB_NODES];
#else
__po_hi_inetnode_t nodes[__PO_HI_NB_DEVICES];
__po_hi_inetnode_t rnodes[__PO_HI_NB_DEVICES];
#endif
int __po_hi_driver_sockets_send (__po_hi_entity_t from,
__po_hi_entity_t to,
......@@ -96,11 +99,7 @@ int __po_hi_driver_sockets_send (__po_hi_entity_t from,
* contains the request.
*/
#ifdef __PO_HI_USE_GIOP
size_to_write = msg->length;
#else
size_to_write = __PO_HI_MESSAGES_MAX_SIZE;
#endif
if (getsockopt (nodes[node].socket, SOL_SOCKET, SO_ERROR, &optval, &optlen) == -1)
{
......@@ -147,8 +146,12 @@ int __po_hi_driver_sockets_send (__po_hi_entity_t from,
return __PO_HI_SUCCESS;
}
void* __po_hi_sockets_receiver_task (void)
extern __po_hi_device_id socket_device_id;
void* __po_hi_sockets_poller (void)
{
__DEBUGMSG ("Poller launched\n");
socklen_t socklen = sizeof (struct sockaddr);
/* See ACCEPT (2) for details on initial value of socklen */
......@@ -156,11 +159,112 @@ void* __po_hi_sockets_receiver_task (void)
int sock;
int max_socket;
fd_set selector;
struct sockaddr_in sa;
__po_hi_node_t dev;
__po_hi_node_t dev_init;
__po_hi_request_t received_request;
__po_hi_msg_t msg;
#ifdef __PO_HI_USE_GIOP
__po_hi_msg_t decoded_msg;
__po_hi_uint32_t has_more;
max_socket = 0; /* Used to compute the max socket number, useful for listen() call */
/*
* We initialize each node socket with -1 value. This value means
* that the socket is not active.
*/
for (dev = 0 ; dev < __PO_HI_NB_DEVICES ; dev++)
{
rnodes[dev].socket = -1;
}
/*
* Create a socket for each node that will communicate with us.
*/
for (dev = 0; dev < __PO_HI_NB_DEVICES ; dev++)
{
if (dev != socket_device_id)
{
sock = accept (nodes[socket_device_id].socket, (struct sockaddr*) &sa, &socklen);
if (read (sock, &dev_init, sizeof (__po_hi_device_id)) != sizeof (__po_hi_device_id))
{
__DEBUGMSG ("[DRIVER SOCKETS] Cannot read device-id for device %d, socket=%d\n", dev, sock);
continue;
}
__DEBUGMSG ("[DRIVER SOCKETS] read device-id %d from socket=%d\n", dev_init, sock);
rnodes[dev].socket = sock;
if (sock > max_socket )
{
max_socket = sock;
}
}
}
__DEBUGMSG ("[DRIVER SOCKETS] Poller initialization finished\n");
__po_hi_wait_initialization ();
/*
* Then, listen and receive data on the socket, identify the node
* which send the data and put it in its message queue
*/
while (1)
{
FD_ZERO( &selector );
for (dev = 0; dev < __PO_HI_NB_DEVICES ; dev++)
{
if ( (dev != socket_device_id ) && ( rnodes[dev].socket != -1 ) )
{
FD_SET( rnodes[dev].socket , &selector );
}
}
if (select (max_socket + 1, &selector, NULL, NULL, NULL) == -1 )
{
#ifdef __PO_HI_DEBUG
__DEBUGMSG ("[DRIVER SOCKETS] Error on select for node %d\n", mynode);
#endif
}
#ifdef __PO_HI_DEBUG
__DEBUGMSG ("[DRIVER SOCKETS] Receive message\n");
#endif
for (dev = 0; dev < __PO_HI_NB_DEVICES ; dev++)
{
if ( (rnodes[dev].socket != -1 ) && FD_ISSET(rnodes[dev].socket, &selector))
{
__DEBUGMSG ("[DRIVER SOCKETS] Receive message from dev %d\n", dev);
memset (msg.content, '\0', __PO_HI_MESSAGES_MAX_SIZE);
len = recv (rnodes[dev].socket, msg.content, __PO_HI_MESSAGES_MAX_SIZE, MSG_WAITALL);
__DEBUGMSG ("[DRIVER SOCKETS] Message received len=%d\n",(int)len);
if (len == 0)
{
rnodes[dev].socket = -1;
continue;
}
__po_hi_unmarshall_request (&received_request, &msg);
__po_hi_main_deliver (&received_request);
}
}
}
return NULL;
}
/*
* Old receiver code that is based on PolyORB-HI-C for AADLv1
* Would be considered as deprecated.
*/
void* __po_hi_sockets_receiver_task (void)
{
socklen_t socklen = sizeof (struct sockaddr);
/* See ACCEPT (2) for details on initial value of socklen */
__po_hi_uint32_t len;
int sock;
int max_socket;
fd_set selector;
__po_hi_msg_t msg;
__po_hi_node_t node;
__po_hi_node_t node_init;
__po_hi_request_t received_request;
......@@ -242,47 +346,6 @@ void* __po_hi_sockets_receiver_task (void)
__DEBUGMSG ("Receive message from node %d\n", node);
#endif
#ifdef __PO_HI_USE_GIOP
/* Decoding GIOP request is implemented as a two-step automata
*
* First step is to decode the header,
* Second step is to decode the payload
*/
__DEBUGMSG ("Using GIOP as protocol stack\n");
__DEBUGMSG (" -> Step 1 decode header\n");
len = read (rnodes[node].socket, &(msg.content), sizeof (__po_hi_giop_msg_hdr_t));
msg.length = len;
has_more = 0;
if (__po_hi_giop_decode_msg (&msg, &decoded_msg, &has_more) == __PO_HI_SUCCESS )
{
#ifdef __PO_HI_DEBUG
__DEBUGMSG ("Message was decoded, has_more=%d\n", has_more);
#endif
__DEBUGMSG (" -> Step 2 decode message\n");
len = recv (rnodes[node].socket, &(msg.content), has_more, MSG_WAITALL);
/* Here, we wait for the _full_ message to come */
msg.length = len;
if (__po_hi_giop_decode_msg (&msg, &decoded_msg, &has_more) == __PO_HI_SUCCESS )
{
/* Put the data in the message queue */
__po_hi_unmarshall_request (&received_request, &decoded_msg);
__po_hi_main_deliver (&received_request);
}
else
{
break;
}
}
else
{
break;
}
#else
__DEBUGMSG ("Using raw protocol stack\n");
len = recv (rnodes[node].socket, &(msg.content), __PO_HI_MESSAGES_MAX_SIZE, MSG_WAITALL);
msg.length = len;
......@@ -298,7 +361,7 @@ void* __po_hi_sockets_receiver_task (void)
__po_hi_unmarshall_request (&received_request, &msg);
__po_hi_main_deliver (&received_request);
#endif
__po_hi_msg_reallocate(&msg); /* re-initialize the message */
}
}
......@@ -307,107 +370,170 @@ void* __po_hi_sockets_receiver_task (void)
}
extern __po_hi_device_id my_id;
void* __po_hi_sockets_poller (void)
/*
* The following code implements the old socket layer
* for PolyORB-HI-C and AADLv1.
* Would be considered as deprecated.
*/
#ifdef __PO_HI_NEED_DRIVER_SOCKETS
void __po_hi_driver_sockets_init (__po_hi_device_id id)
{
__DEBUGMSG ("Poller launched\n");
socklen_t socklen = sizeof (struct sockaddr);
/* See ACCEPT (2) for details on initial value of socklen */
__po_hi_uint32_t len;
int sock;
int max_socket;
fd_set selector;
int i;
int ret;
int reuse;
char *tmp;
__po_hi_time_t mytime;
struct sockaddr_in sa;
__po_hi_node_t dev;
__po_hi_node_t dev_init;
__po_hi_request_t received_request;
__po_hi_msg_t msg;
struct hostent* hostinfo;
max_socket = 0; /* Used to compute the max socket number, useful for listen() call */
char dev_addr[16];
int node;
/*
* We initialize each node socket with -1 value. This value means
* that the socket is not active.
*/
for (dev = 0 ; dev < __PO_HI_NB_DEVICES ; dev++)
memset (dev_addr, '\0', 16);
for (node = 0 ; node < __PO_HI_NB_NODES ; node++)
{
rnodes[dev].socket = -1;
nodes[node].socket = -1;
}
/*
* Create a socket for each node that will communicate with us.
* If the current node port has a port number, then it has to
* listen to other nodes. So, we create a socket, bind it and
* listen to other nodes.
*/
for (dev = 0; dev < __PO_HI_NB_DEVICES ; dev++)
if ( node_port[mynode] != __PO_HI_NOPORT )
{
if (dev != my_id)
nodes[mynode].socket = socket (AF_INET, SOCK_STREAM, 0);
if (nodes[mynode].socket == -1 )
{
sock = accept (nodes[my_id].socket, (struct sockaddr*) &sa, &socklen);
#ifdef __PO_HI_DEBUG
__DEBUGMSG ("Cannot create socket for node %d\n", mynode);
#endif
return;
}
if (read (sock, &dev_init, sizeof (__po_hi_device_id)) != sizeof (__po_hi_device_id))
{
__DEBUGMSG ("[DRIVER SOCKETS] Cannot read device-id for device %d, socket=%d\n", dev, sock);
continue;
}
__DEBUGMSG ("[DRIVER SOCKETS] read device-id %d from socket=%d\n", dev_init, sock);
rnodes[dev].socket = sock;
if (sock > max_socket )
{
max_socket = sock;
}
reuse = 1;
setsockopt (nodes[mynode].socket, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof (reuse));
sa.sin_addr.s_addr = htonl (INADDR_ANY); /* We listen on all adresses */
sa.sin_family = AF_INET;
sa.sin_port = htons (node_port[mynode]); /* Port provided by the generated code */
if( bind( nodes[mynode].socket , ( struct sockaddr * ) &sa , sizeof( struct sockaddr_in ) ) < 0 )
{
#ifdef __PO_HI_DEBUG
__DEBUGMSG ("Unable to bind socket and port on socket %d\n", nodes[mynode].socket);
#endif
}
if( listen( nodes[mynode].socket , __PO_HI_NB_ENTITIES ) < 0 )
{
#ifdef __PO_HI_DEBUG
__DEBUGMSG ("Cannot listen on socket %d\n", nodes[mynode].socket);
#endif
}
/*
* Create the thread which receive all data from other
* nodes. This thread will execute the function
* __po_hi_receiver_task
*/
__po_hi_initialize_add_task ();
__po_hi_create_generic_task
(-1, 0,__PO_HI_MAX_PRIORITY, 0, __po_hi_sockets_receiver_task);
}
__DEBUGMSG ("[DRIVER SOCKETS] Poller initialization finished\n");
__po_hi_wait_initialization ();
/*
* Then, listen and receive data on the socket, identify the node
* which send the data and put it in its message queue
* For each node in the sytem that may communicate with the current
* node we create a socket. This socket will be used to send data.
*/
while (1)
for (node = 0 ; node < __PO_HI_NB_NODES ; node++ )
{
FD_ZERO( &selector );
for (dev = 0; dev < __PO_HI_NB_DEVICES ; dev++)
if ( (node != mynode) && (node_port[node] != __PO_HI_NOPORT) && (nodes[node].socket == -1) )
{
if ( (dev != my_id ) && ( rnodes[dev].socket != -1 ) )
while (1)
{
FD_SET( rnodes[dev].socket , &selector );
}
}
nodes[node].socket = socket (AF_INET, SOCK_STREAM, 0);
if (select (max_socket + 1, &selector, NULL, NULL, NULL) == -1 )
{
if (nodes[node].socket == -1 )
{
#ifdef __PO_HI_DEBUG
__DEBUGMSG ("[DRIVER SOCKETS] Error on select for node %d\n", mynode);
#endif
}
__DEBUGMSG ("Socket for node %d is not created", node);
#endif
return;
}