Commit 891eb58d authored by julien.delange's avatar julien.delange
Browse files

add new socket driver that rely on AADL devices configuration



git-svn-id: https://tecsw.estec.esa.int/svn/taste/trunk/po-hi-c@705 129961e7-ef38-4bb5-a8f7-c9a525a55882
parent ba5830aa
......@@ -48,7 +48,7 @@ __po_hi_uint8_t __po_hi_get_endianness (const __po_hi_node_t node);
#if __PO_HI_NB_DEVICES > 0
__po_hi_device_id __po_hi_get_device_from_port (const __po_hi_port_t port);
char* __po_hi_get_device_naming (const __po_hi_port_t port);
char* __po_hi_get_device_naming (const __po_hi_device_id dev);
#endif
#endif /* __PO_HI_TRANSPORT__ */
......@@ -17,6 +17,7 @@
#include <po_hi_config.h>
#include <po_hi_task.h>
#include <po_hi_transport.h>
#include <po_hi_gqueue.h>
#include <po_hi_debug.h>
#include <po_hi_types.h>
#include <po_hi_messages.h>
......@@ -63,25 +64,36 @@
* listen socket. This array is used only by the receiver_task
*/
__po_hi_inetnode_t nodes[__PO_HI_NB_NODES];
__po_hi_inetnode_t rnodes[__PO_HI_NB_NODES];
__po_hi_inetnode_t nodes[__PO_HI_NB_DEVICES];
__po_hi_inetnode_t rnodes[__PO_HI_NB_DEVICES];
int __po_hi_driver_sockets_asn1_send (__po_hi_entity_t from,
__po_hi_entity_t to,
__po_hi_msg_t* msg)
extern __po_hi_device_id my_id;
int __po_hi_driver_sockets_asn1_send (__po_hi_task_id task_id,
__po_hi_port_t port)
{
__po_hi_node_t node;
int len;
int size_to_write;
int optval = 0;
socklen_t optlen = 0;
int len;
int size_to_write;
int optval = 0;
socklen_t optlen = 0;
__po_hi_device_id associated_device;
__po_hi_local_port_t local_port;
__po_hi_request_t* request;
__po_hi_msg_t msg;
__po_hi_port_t destination_port;
local_port = __po_hi_get_local_port_from_global_port (port);
request = __po_hi_gqueue_get_most_recent_value (task_id, local_port);
destination_port = __po_hi_gqueue_get_destination (task_id, local_port, 0);
node = __po_hi_transport_get_node_from_entity (to);
associated_device = __po_hi_get_device_from_port (destination_port);
if (nodes[node].socket == -1 )
if (nodes[associated_device].socket == -1 )
{
#ifdef __PO_HI_DEBUG
__DEBUGMSG (" [... failure ...]\n");
__DEBUGMSG (" [DRIVER SOCKETS] Invalid socket for port-id %d, device-id %d\n", destination_port, associated_device);
#endif
return __PO_HI_ERROR_TRANSPORT_SEND;
}
......@@ -93,19 +105,19 @@ int __po_hi_driver_sockets_asn1_send (__po_hi_entity_t from,
size_to_write = __PO_HI_MESSAGES_MAX_SIZE;
if (getsockopt (nodes[node].socket, SOL_SOCKET, SO_ERROR, &optval, &optlen) == -1)
if (getsockopt (nodes[associated_device].socket, SOL_SOCKET, SO_ERROR, &optval, &optlen) == -1)
{
__DEBUGMSG (" [error getsockopt() in file %s, line%d ]\n", __FILE__, __LINE__);
close (nodes[node].socket);
nodes[node].socket = -1;
close (nodes[associated_device].socket);
nodes[associated_device].socket = -1;
return __PO_HI_ERROR_TRANSPORT_SEND;
}
if (optval != 0)
{
__DEBUGMSG (" [error getsockopt() return code in file %s, line%d ]\n", __FILE__, __LINE__);
close (nodes[node].socket);
nodes[node].socket = -1;
close (nodes[associated_device].socket);
nodes[associated_device].socket = -1;
return __PO_HI_ERROR_TRANSPORT_SEND;
}
......@@ -114,22 +126,29 @@ int __po_hi_driver_sockets_asn1_send (__po_hi_entity_t from,
if (signal (SIGPIPE, SIG_IGN) == SIG_ERR)
{
__DEBUGMSG (" [error signal() return code in file %s, line%d ]\n", __FILE__, __LINE__);
close (nodes[node].socket);
nodes[node].socket = -1;
close (nodes[associated_device].socket);
nodes[associated_device].socket = -1;
return __PO_HI_ERROR_TRANSPORT_SEND;
}
__po_hi_msg_reallocate (&msg);
request->port = destination_port;
__po_hi_marshall_request (request, &msg);
#ifdef __PO_HI_DEBUG
__po_hi_messages_debug (msg);
__po_hi_messages_debug (&msg);
#endif
len = write (nodes[node].socket, &(msg->content), size_to_write);
len = write (nodes[associated_device].socket, &(msg.content), size_to_write);
if (len != size_to_write)
{
__DEBUGMSG (" [error write() length in file %s, line%d ]\n", __FILE__, __LINE__);
close (nodes[node].socket);
nodes[node].socket = -1;
close (nodes[associated_device].socket);
nodes[associated_device].socket = -1;
return __PO_HI_ERROR_TRANSPORT_SEND;
}
......@@ -149,8 +168,8 @@ void* __po_hi_sockets_asn1_poller (void)
int max_socket;
fd_set selector;
__po_hi_msg_t msg;
__po_hi_node_t node;
__po_hi_node_t node_init;
__po_hi_node_t dev;
__po_hi_node_t dev_init;
__po_hi_request_t received_request;
struct sockaddr_in sa;
......@@ -160,37 +179,34 @@ void* __po_hi_sockets_asn1_poller (void)
* We initialize each node socket with -1 value. This value means
* that the socket is not active.
*/
for (node = 0 ; node < __PO_HI_NB_NODES ; node++)
for (dev = 0 ; dev < __PO_HI_NB_DEVICES ; dev++)
{
rnodes[node].socket = -1;
rnodes[dev].socket = -1;
}
/*
* Create a socket for each node that will communicate with us.
*/
for (node = 0; node < __PO_HI_NB_NODES ; node++)
for (dev = 0; dev < __PO_HI_NB_DEVICES ; dev++)
{
if (node != mynode )
if (dev != my_id)
{
sock = accept (nodes[mynode].socket, (struct sockaddr*) &sa, &socklen);
sock = accept (nodes[my_id].socket, (struct sockaddr*) &sa, &socklen);
if (read (sock, &node_init, sizeof (__po_hi_node_t)) != sizeof (__po_hi_node_t))
if (read (sock, &dev_init, sizeof (__po_hi_device_id)) != sizeof (__po_hi_device_id))
{
#ifdef __PO_HI_DEBUG
__DEBUGMSG ("Cannot read node-id for socket %d\n", sock);
#endif
__DEBUGMSG ("[DRIVER SOCKETS] Cannot read device-id for device %d, socket=%d\n", dev, sock);
continue;
}
rnodes[node].socket = sock;
__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;
}
}
}
#ifdef __PO_HI_DEBUG
__DEBUGMSG ("Receiver initialization finished\n");
#endif
__DEBUGMSG ("[DRIVER SOCKETS] Poller initialization finished\n");
__po_hi_wait_initialization ();
/*
......@@ -200,43 +216,39 @@ void* __po_hi_sockets_asn1_poller (void)
while (1)
{
FD_ZERO( &selector );
for (node = 0; node < __PO_HI_NB_NODES ; node++)
for (dev = 0; dev < __PO_HI_NB_DEVICES ; dev++)
{
if ( (node != mynode ) && ( rnodes[node].socket != -1 ) )
if ( (dev != my_id ) && ( rnodes[dev].socket != -1 ) )
{
FD_SET( rnodes[node].socket , &selector );
FD_SET( rnodes[dev].socket , &selector );
}
}
if (select (max_socket + 1, &selector, NULL, NULL, NULL) == -1 )
{
#ifdef __PO_HI_DEBUG
__DEBUGMSG ("Error on select for node %d\n", mynode);
__DEBUGMSG ("[DRIVER SOCKETS] Error on select for node %d\n", mynode);
#endif
}
#ifdef __PO_HI_DEBUG
__DEBUGMSG ("Receive message\n");
__DEBUGMSG ("[DRIVER SOCKETS] Receive message\n");
#endif
for (node = 0; node < __PO_HI_NB_NODES ; node++)
for (dev = 0; dev < __PO_HI_NB_DEVICES ; dev++)
{
if ( (rnodes[node].socket != -1 ) && FD_ISSET(rnodes[node].socket, &selector))
if ( (rnodes[dev].socket != -1 ) && FD_ISSET(rnodes[dev].socket, &selector))
{
#ifdef __PO_HI_DEBUG
__DEBUGMSG ("Receive message from node %d\n", node);
#endif
__DEBUGMSG ("Using raw protocol stack\n");
len = recv (rnodes[node].socket, &(msg.content), __PO_HI_MESSAGES_MAX_SIZE, MSG_WAITALL);
__DEBUGMSG ("[DRIVER SOCKETS] Receive message from dev %d\n", dev);
len = recv (rnodes[dev].socket, &(msg.content), __PO_HI_MESSAGES_MAX_SIZE, MSG_WAITALL);
msg.length = len;
if (len != __PO_HI_MESSAGES_MAX_SIZE )
{
__DEBUGMSG ("ERROR, %u %d", (unsigned int) len, __PO_HI_MESSAGES_MAX_SIZE);
close (rnodes[node].socket);
rnodes[node].socket = -1;
__DEBUGMSG ("[DRIVER SOCKETS] ERROR, %u %d", (unsigned int) len, __PO_HI_MESSAGES_MAX_SIZE);
close (rnodes[dev].socket);
rnodes[dev].socket = -1;
continue;
}
__DEBUGMSG ("Message delivered");
__DEBUGMSG ("[DRIVER SOCKETS] Message delivered");
__po_hi_unmarshall_request (&received_request, &msg);
......
......@@ -27,6 +27,7 @@
#include <po_hi_debug.h>
#include <po_hi_transport.h>
#include <po_hi_common.h>
#include <po_hi_main.h>
#include <po_hi_time.h>
......@@ -35,28 +36,230 @@
#include <drivers/po_hi_driver_sockets_common.h>
#include <drivers/po_hi_driver_sockets.h>
#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
__po_hi_device_id my_id;
#ifdef __PO_HI_NEED_DRIVER_SOCKETS_ASN1
void __po_hi_driver_sockets_init (__po_hi_device_id id)
{
int i;
int ret;
int reuse;
char *tmp;
__po_hi_uint16_t node;
__po_hi_uint16_t dev;
__po_hi_time_t mytime;
struct sockaddr_in sa;
struct hostent* hostinfo;
/* Initialization of all sockets */
char* dev_conf;
char dev_addr[16];
int dev_port;
int node;
for (node = 0 ; node < __PO_HI_NB_NODES ; node++)
my_id = id;
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, "eth %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);
/*
* 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.
*/
if (dev_port != 0)
{
nodes[id].socket = socket (AF_INET, SOCK_STREAM, 0);
if (nodes[id].socket == -1 )
{
#ifdef __PO_HI_DEBUG
__DEBUGMSG ("Cannot create socket for device %d\n", id);
#endif
return;
}
reuse = 1;
setsockopt (nodes[id].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 (dev_port); /* Port provided by the generated code */
if( bind( nodes[id].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[id].socket);
#endif
}
if( listen( nodes[id].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_asn1_poller);
}
/*
* 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.
*/
for (dev = 0 ; dev < __PO_HI_NB_DEVICES ; dev++ )
{
if (dev == id)
{
continue;
}
memset (dev_addr, '\0', 16);
dev_port = 0;
dev_conf = __po_hi_get_device_naming (dev);
if (sscanf (dev_conf, "eth %s %d", dev_addr, &dev_port) == 0)
{
__DEBUGMSG ("[DRIVER SOCKETS] Unable to parse device configuration (id=%d)\n", id);
continue;
}
__DEBUGMSG ("[DRIVER SOCKETS] Configuration for device %d, addr=%s, port=%d\n", dev, dev_addr, dev_port);
if (dev_port == 0)
{
continue;
}
while (1)
{
nodes[dev].socket = socket (AF_INET, SOCK_STREAM, 0);
if (nodes[dev].socket == -1 )
{
#ifdef __PO_HI_DEBUG
__DEBUGMSG ("[DRIVER SOCKETS] Socket for node %d is not created", node);
#endif
return;
}
hostinfo = gethostbyname ((char*)dev_addr);
if (hostinfo == NULL )
{
__DEBUGMSG ("[DRIVER SOCKETS] Error while getting host informations for device %d\n", dev);
}
sa.sin_port = htons (dev_port);
sa.sin_family = AF_INET;
/* The following lines are used to copy the
* hostinfo->h_length to the sa.sin_addr member. Most
* of program use the memcpy to do that, but the
* RT-POSIX profile we use forbid the use of this
* function. We use a loop instead to perform the
* copy. So, these lines replace the code :
*
* memcpy( (char*) &( sa.sin_addr ) , (char*)hostinfo->h_addr , hostinfo->h_length );
*/
tmp = (char*) &(sa.sin_addr);
for (i=0 ; i<hostinfo->h_length ; i++)
{
tmp[i] = hostinfo->h_addr[i];
}
/*
* We try to connect on the remote host. We try every
* second to connect on.
*/
ret = connect (nodes[dev].socket,
(struct sockaddr*) &sa ,
sizeof (struct sockaddr_in));
if (ret == 0)
{
__DEBUGMSG ("[DRIVER SOCKETS] Send my id (%d)\n", id);
if (write (nodes[dev].socket, &id, sizeof (__po_hi_device_id)) != sizeof (__po_hi_device_id))
{
__DEBUGMSG ("[DRIVER SOCKETS] Device %d cannot send his id\n", id);
}
break;
}
if (close (nodes[dev].socket))
{
__DEBUGMSG ("[DRIVER SOCKETS] Cannot close socket %d\n", nodes[dev].socket);
}
/*
* We wait 500ms each time we try to connect on the
* remote host
*/
__po_hi_get_time (&mytime);
__DEBUGMSG ("[DRIVER SOCKETS] Cannot connect on device %d, wait 500ms\n", dev);
__po_hi_delay_until (__po_hi_add_times (mytime, __po_hi_milliseconds (500)));
}
}
}
#else
void __po_hi_driver_sockets_init (__po_hi_device_id id)
{
int i;
int ret;
int reuse;
char *tmp;
__po_hi_time_t mytime;
struct sockaddr_in sa;
struct hostent* hostinfo;
char* dev_conf;
char dev_addr[16];
int dev_port;
int node;
memset (dev_addr, '\0', 16);
for (node = 0 ; node < __PO_HI_NB_NODES ; node++)
{
nodes[node].socket = -1;
}
/*
* 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
......@@ -103,16 +306,8 @@ void __po_hi_driver_sockets_init (__po_hi_device_id id)
__po_hi_initialize_add_task ();
#ifdef __PO_HI_NEED_DRIVER_SOCKETS
__po_hi_create_generic_task
(-1, 0,__PO_HI_MAX_PRIORITY, 0, __po_hi_sockets_receiver_task);
#endif
#ifdef __PO_HI_NEED_DRIVER_SOCKETS_ASN1
__po_hi_create_generic_task
(-1, 0,__PO_HI_MAX_PRIORITY, 0, __po_hi_sockets_asn1_poller);
#endif
}
/*
......@@ -200,5 +395,7 @@ void __po_hi_driver_sockets_init (__po_hi_device_id id)
}
}
}
#endif
#endif /* __PO_HI_NEED_DRIVER_SOCKETS || __PO_HI_NEED_DRIVER_SOCKETS_ASN1 */
......@@ -150,9 +150,9 @@ __po_hi_uint8_t __po_hi_get_endianness (const __po_hi_node_t node)
}
#if __PO_HI_NB_DEVICES > 0
char* __po_hi_get_device_naming (const __po_hi_port_t port)
char* __po_hi_get_device_naming (const __po_hi_device_id dev)
{
return __po_hi_devices_naming[port];
return __po_hi_devices_naming[dev];
}
__po_hi_device_id __po_hi_get_device_from_port (const __po_hi_port_t port)
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment