po_hi_driver_sockets.c 19.7 KB
Newer Older
1
2
3
4
5
6
7
/*
 * This is a part of PolyORB-HI-C distribution, a minimal
 * middleware written for generated code from AADL models.
 * You should use it with the Ocarina toolsuite.
 *
 * For more informations, please visit http://ocarina.enst.fr
 *
8
 * Copyright (C) 2010, European Space Agency
9
10
11
 * Copyright (C) 2007-2008, GET-Telecom Paris.
 */

12
#include <deployment.h>
julien.delange's avatar
julien.delange committed
13
#include <marshallers.h>
14

julien.delange's avatar
julien.delange committed
15
16
#if (defined (__PO_HI_NEED_DRIVER_SOCKETS) || \
     defined (__PO_HI_NEED_DRIVER_RTEMS_NE2000_SOCKETS))
17

18
19
20
21
22
23
24
25
26
#include <po_hi_config.h>
#include <po_hi_task.h>
#include <po_hi_transport.h>
#include <po_hi_debug.h>
#include <po_hi_types.h>
#include <po_hi_messages.h>
#include <po_hi_returns.h>
#include <po_hi_main.h>
#include <po_hi_task.h>
27
#include <po_hi_gqueue.h>
28
#include <drivers/po_hi_driver_sockets.h>
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

#include <activity.h>

#include <signal.h>
#include <string.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/time.h>

/*
44
 * This file (po_hi_sockets.c) provides function to handle
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
 * communication between nodes in PolyORB-HI-C.  We don't use a
 * protocol to send data. For each data sent, we send before the
 * entity number provided by the generated file deployment.h, then, we
 * send the message.  Each entity has a fixed size
 * (sizeof(__po_hi_entity_t)), and each message has a max fixed size
 * (see the __PO_HI_MESSAGES_MAX_SIZE macro).
 */

/* The following declarations avoid conflicts
 * with current generated code.
 */

#ifndef __PO_HI_NB_NODES
#define __PO_HI_NB_NODES 1
#endif

/*
 * We have two arrays of sockets. The first array (nodes) is used to
63
 * send data to other nodes. A special socket if nodes[__po_hi_mynode] : this
64
65
66
67
68
 * socket is used to listen others processes.  The second array
 * (rnodes), is used to store all socket that are created by the
 * listen socket. This array is used only by the receiver_task
 */

julien.delange's avatar
julien.delange committed
69
70
__po_hi_inetnode_t nodes[__PO_HI_NB_DEVICES];
__po_hi_inetnode_t rnodes[__PO_HI_NB_DEVICES];
julien.delange's avatar
julien.delange committed
71

72
__po_hi_device_id socket_device_id;
73

74
75
76
int __po_hi_driver_sockets_send (__po_hi_task_id task_id,
                                 __po_hi_port_t port)
{
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
   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_port_t             destination_port;
   __po_hi_msg_t              msg;
   __po_hi_protocol_t         protocol_id;
   __po_hi_protocol_conf_t*   protocol_conf;

   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);
   associated_device       = __po_hi_get_device_from_port (destination_port);
   protocol_id             = __po_hi_transport_get_protocol (port, destination_port);
   protocol_conf           = __po_hi_transport_get_protocol_configuration (protocol_id);
95

96
97
98
99
100
101
   if (request->port == -1)
   {

#ifdef __PO_HI_DEBUG
      __DEBUGMSG (" [DRIVER SOCKETS] No data to write on port %d\n", port);
#endif
102
      return __PO_HI_ERROR_TRANSPORT_SEND;
103
104
   }

105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
   if (nodes[associated_device].socket == -1 )
   {
#ifdef __PO_HI_DEBUG
      __DEBUGMSG (" [DRIVER SOCKETS] Invalid socket for port-id %d, device-id %d\n", destination_port, associated_device);
#endif
      return __PO_HI_ERROR_TRANSPORT_SEND;		
   }

   /*
    * After sending the entity identifier, we send the message which
    * contains the request.
    */

   size_to_write = __PO_HI_MESSAGES_MAX_SIZE;

   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[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[associated_device].socket);
      nodes[associated_device].socket = -1;
      return __PO_HI_ERROR_TRANSPORT_SEND;		
   }

   /* Ignore SIGPIPE to be able to recover from errors instead of crashing the node */

   if (signal (SIGPIPE, SIG_IGN) == SIG_ERR)
   {
      __DEBUGMSG (" [error signal() return code in file %s, line%d ]\n", __FILE__, __LINE__);
      close (nodes[associated_device].socket);
      nodes[associated_device].socket = -1;
      return __PO_HI_ERROR_TRANSPORT_SEND;
   }
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159

   switch (protocol_id)
   {
#ifdef __PO_HI_USE_PROTOCOL_MYPROTOCOL_I
      case virtual_bus_myprotocol_i:
      {
         protocol_conf->marshaller(request, &msg);
         break;
      }
#endif
      default: 
      {
         request->port = destination_port;
         __po_hi_msg_reallocate (&msg);
         __po_hi_marshall_request (request, &msg);
160
161

#ifdef __PO_HI_DEBUG
162
         __po_hi_messages_debug (&msg);
163
164
#endif

165
         len = write (nodes[associated_device].socket, &(msg.content), size_to_write);
166

167
168
169
170
171
172
173
174
175
         if (len != size_to_write)
         {
            __DEBUGMSG (" [error write() length in file %s, line%d ]\n", __FILE__, __LINE__);
            close (nodes[associated_device].socket);
            nodes[associated_device].socket = -1;
            return __PO_HI_ERROR_TRANSPORT_SEND;		
         }
         break;
      }
176
177
178
179
180
181
   }

   return __PO_HI_SUCCESS;
}


182
void* __po_hi_sockets_poller (const __po_hi_device_id dev_id)
183
{
184
   (void) dev_id;
185
   __DEBUGMSG ("Poller launched, device-id=%d\n", socket_device_id);
julien.delange's avatar
julien.delange committed
186
187
188
189
190
191
192
   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;
julien.delange's avatar
julien.delange committed
193
   struct sockaddr_in sa;
194
   __po_hi_device_id  dev;
julien.delange's avatar
julien.delange committed
195
196
   __po_hi_node_t     dev_init;
   __po_hi_request_t  received_request;
julien.delange's avatar
julien.delange committed
197
   __po_hi_msg_t      msg;
198
   int                established = 0; 
julien.delange's avatar
julien.delange committed
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215

   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++)
   {
julien.delange's avatar
julien.delange committed
216
      if (dev != socket_device_id)
julien.delange's avatar
julien.delange committed
217
      {
218
         __DEBUGMSG ("[DRIVER SOCKETS] Poller waits for connection with device %d\n", dev);
julien.delange's avatar
julien.delange committed
219

220
         /*
221
         __PO_HI_SET_SOCKET_TIMEOUT(nodes[socket_device_id].socket,5);
222
         */
223
224
225
226

         established = 0;

         while (established == 0)
julien.delange's avatar
julien.delange committed
227
         {
228
229
230
231
            sock = accept (nodes[socket_device_id].socket, (struct sockaddr*) &sa, &socklen);

            __PO_HI_SET_SOCKET_TIMEOUT(sock,10);

232
#ifndef __PO_HI_USE_PROTOCOL_MYPROTOCOL_I
233
234
235
236
237
238
239
            if (read (sock, &dev_init, sizeof (__po_hi_device_id)) != sizeof (__po_hi_device_id))
            {
               established = 0;
               __DEBUGMSG ("[DRIVER SOCKETS] Cannot read device-id for device %d, socket=%d\n", dev, sock);
            }
            else
            {
240
               __DEBUGMSG ("[DRIVER SOCKETS] read device-id %d from socket=%d\n", dev_init, sock);
241
242
               established = 1;
            }
243
244
245
#else
            established = 1;
#endif
julien.delange's avatar
julien.delange committed
246
247
248
249
250
251
252
253
         }
         rnodes[dev].socket = sock;
         if (sock > max_socket )
         {
            max_socket = sock;
         }	  
      }
   }
254
   __DEBUGMSG ("[DRIVER SOCKETS] Poller initialization finished, waiting for other tasks\n");
julien.delange's avatar
julien.delange committed
255
   __po_hi_wait_initialization ();
256
   __DEBUGMSG ("[DRIVER SOCKETS] Other tasks are initialized, let's start the polling !\n");
julien.delange's avatar
julien.delange committed
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275

   /*
    * 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
276
         __DEBUGMSG ("[DRIVER SOCKETS] Error on select for node %d\n", __po_hi_mynode);
julien.delange's avatar
julien.delange committed
277
278
279
280
#endif 
      }
#ifdef __PO_HI_DEBUG
      __DEBUGMSG ("[DRIVER SOCKETS] Receive message\n");
281
#endif
julien.delange's avatar
julien.delange committed
282
283
284

      for (dev = 0; dev < __PO_HI_NB_DEVICES ; dev++)
      {
285
         __DEBUGMSG ("[DRIVER SOCKETS] Try to watch if it comes from device %d (socket=%d)\n", dev, rnodes[dev].socket);
julien.delange's avatar
julien.delange committed
286
287
288
289
290
         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);
291
            msg.length = len;
julien.delange's avatar
julien.delange committed
292
293
            __DEBUGMSG ("[DRIVER SOCKETS] Message received len=%d\n",(int)len);

294
295
296
297
298
#ifdef __PO_HI_DEBUG
   __po_hi_messages_debug (&msg);
#endif


julien.delange's avatar
julien.delange committed
299
300
            if (len == 0)
            {
301
302

               __DEBUGMSG ("[DRIVER SOCKETS] Zero size from device %d\n",dev);
julien.delange's avatar
julien.delange committed
303
304
305
306
307
308
               rnodes[dev].socket = -1;
               continue;
            }

            __po_hi_unmarshall_request (&received_request, &msg);

309

julien.delange's avatar
julien.delange committed
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
            __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 */

327
328
329
330
331
332
333
334
335
336
   __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;
   struct sockaddr_in         sa;
   __po_hi_protocol_conf_t*   protocol_conf;
julien.delange's avatar
julien.delange committed
337

338

julien.delange's avatar
julien.delange committed
339
340
341
342
343
344
345
346
   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 (node = 0 ; node < __PO_HI_NB_NODES ; node++)
   {
347
      rnodes[node].socket = -1;
julien.delange's avatar
julien.delange committed
348
349
350
351
352
353
354
   }

   /*
    * Create a socket for each node that will communicate with us.
    */
   for (node = 0; node < __PO_HI_NB_NODES ; node++)
   {
355
      if (node != __po_hi_mynode )
julien.delange's avatar
julien.delange committed
356
      {
357
         sock = accept (nodes[__po_hi_mynode].socket, (struct sockaddr*) &sa, &socklen);
358
359
360
361
         if (sock == -1)
         {
            __DEBUGMSG ("accept() failed, return=%d\n", sock);
         }
julien.delange's avatar
julien.delange committed
362

363
364
365
         __DEBUGMSG ("accept() success, return=%d\n", sock);

#ifndef __PO_HI_USE_PROTOCOL_MYPROTOCOL_I
julien.delange's avatar
julien.delange committed
366
367
368
369
370
         if (read (sock, &node_init, sizeof (__po_hi_node_t)) != sizeof (__po_hi_node_t))
         {
            __DEBUGMSG ("Cannot read node-id for socket %d\n", sock);
            continue;
         }
371
#endif
372

julien.delange's avatar
julien.delange committed
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
         rnodes[node].socket = sock;
         if (sock > max_socket )
         {
            max_socket = sock;
         }	  
      }
   }
   __DEBUGMSG ("Receiver 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)
388
   {
julien.delange's avatar
julien.delange committed
389
390
391
      FD_ZERO( &selector );
      for (node = 0; node < __PO_HI_NB_NODES ; node++)
      {
392
         if ( (node != __po_hi_mynode ) && ( rnodes[node].socket != -1 ) )
julien.delange's avatar
julien.delange committed
393
394
395
396
397
398
399
         {
            FD_SET( rnodes[node].socket , &selector );
         }
      }

      if (select (max_socket + 1, &selector, NULL, NULL, NULL) == -1 )
      {
400
#ifdef __PO_HI_DEBUG
401
         __DEBUGMSG ("Error on select for node %d\n", __po_hi_mynode);
402
#endif 
julien.delange's avatar
julien.delange committed
403
      }
404
#ifdef __PO_HI_DEBUG
julien.delange's avatar
julien.delange committed
405
      __DEBUGMSG ("Receive message\n");
406
#endif
julien.delange's avatar
julien.delange committed
407
408
409

      for (node = 0; node < __PO_HI_NB_NODES ; node++)
      {
410
         if ( (rnodes[node].socket != -1 ) && FD_ISSET(rnodes[node].socket, &selector))
julien.delange's avatar
julien.delange committed
411
         {
412
#ifdef __PO_HI_DEBUG
julien.delange's avatar
julien.delange committed
413
            __DEBUGMSG ("Receive message from node %d\n", node);
414
#endif
julien.delange's avatar
julien.delange committed
415

416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
#ifdef __PO_HI_USE_PROTOCOL_MYPROTOCOL_I

            __DEBUGMSG ("Using raw protocol stack\n");
            len = recv (rnodes[node].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;
               continue;
            }
            __DEBUGMSG ("Message delivered");


            protocol_conf = __po_hi_transport_get_protocol_configuration (virtual_bus_myprotocol_i);
            protocol_conf->unmarshaller (&received_request, &msg);
#else

julien.delange's avatar
julien.delange committed
435
436
437
438
439
440
441
442
443
444
445
446
447
            __DEBUGMSG ("Using raw protocol stack\n");
            len = recv (rnodes[node].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;
               continue;
            }
            __DEBUGMSG ("Message delivered");

            __po_hi_unmarshall_request (&received_request, &msg);
448
#endif
julien.delange's avatar
julien.delange committed
449
450

            __po_hi_main_deliver (&received_request);
julien.delange's avatar
julien.delange committed
451

julien.delange's avatar
julien.delange committed
452
453
454
            __po_hi_msg_reallocate(&msg);        /* re-initialize the message */
         }
      }
455
   }  
julien.delange's avatar
julien.delange committed
456
   return NULL;
457
458
}

julien.delange's avatar
julien.delange committed
459
void __po_hi_driver_sockets_init (__po_hi_device_id id)
460
{
julien.delange's avatar
julien.delange committed
461
462
463
464
   int                i;
   int                ret;
   int                reuse;
   char               *tmp;
465
   __po_hi_uint16_t   dev;
julien.delange's avatar
julien.delange committed
466
   __po_hi_time_t     mytime;
467
468
   __po_hi_time_t     tmptime;
   __po_hi_time_t     current_time;
469
   struct sockaddr_in sa;
julien.delange's avatar
julien.delange committed
470
   struct hostent*    hostinfo;
471
472


473
474
475
476
   __po_hi_c_ip_conf_t* ipconf;
   char ip_addr[16];
   int ip_port;
   int node;
julien.delange's avatar
julien.delange committed
477

478
   socket_device_id = id;
julien.delange's avatar
julien.delange committed
479

480
   for (node = 0 ; node < __PO_HI_NB_DEVICES ; node++)
481
   {
julien.delange's avatar
julien.delange committed
482
      nodes[node].socket = -1;
483
484
   }

485
486
487
488
489
   ipconf = (__po_hi_c_ip_conf_t*)__po_hi_get_device_configuration (id);
   ip_port = (int)ipconf->port;

   __DEBUGMSG ("My configuration, addr=%s, port=%lld\n", ipconf->address, ipconf->port );

490
   /*
julien.delange's avatar
julien.delange committed
491
492
493
    * 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.
494
    */
495
   if (ip_port != 0)
496
   {
497
      nodes[id].socket = socket (AF_INET, SOCK_STREAM, 0);
julien.delange's avatar
julien.delange committed
498

499
      if (nodes[id].socket == -1 )
500
      {
julien.delange's avatar
julien.delange committed
501
#ifdef __PO_HI_DEBUG
502
         __DEBUGMSG ("Cannot create socket for device %d\n", id);
julien.delange's avatar
julien.delange committed
503
504
505
#endif
         return;
      }
506

julien.delange's avatar
julien.delange committed
507
      reuse = 1;
508
      setsockopt (nodes[id].socket, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof (reuse));
julien.delange's avatar
julien.delange committed
509
510
511

      sa.sin_addr.s_addr = htonl (INADDR_ANY);   /* We listen on all adresses */
      sa.sin_family = AF_INET;                   
512
      sa.sin_port = htons (ip_port);   /* Port provided by the generated code */
julien.delange's avatar
julien.delange committed
513

514
      if( bind( nodes[id].socket , ( struct sockaddr * ) &sa , sizeof( struct sockaddr_in ) ) < 0 )
julien.delange's avatar
julien.delange committed
515
516
      {
#ifdef __PO_HI_DEBUG
517
         __DEBUGMSG ("Unable to bind socket and port on socket %d\n", nodes[id].socket);
julien.delange's avatar
julien.delange committed
518
519
520
#endif
      }

521
      if( listen( nodes[id].socket , __PO_HI_NB_ENTITIES ) < 0 )
julien.delange's avatar
julien.delange committed
522
523
      {
#ifdef __PO_HI_DEBUG
524
         __DEBUGMSG ("Cannot listen on socket %d\n", nodes[id].socket);
julien.delange's avatar
julien.delange committed
525
#endif
526
      }
julien.delange's avatar
julien.delange committed
527
528
529
530
531
532
533
534
535
536

      /* 
       * 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 
537
         (-1, 0,__PO_HI_MAX_PRIORITY, 0, __po_hi_sockets_poller);
538
539
540
   }

   /*
julien.delange's avatar
julien.delange committed
541
542
    * 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.
543
    */
544
   for (dev = 0 ; dev < __PO_HI_NB_DEVICES ; dev++ )
545
   {
546
      if (dev == id)
547
      {
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
         continue;
      }

      __DEBUGMSG ("[DRIVER SOCKETS] Will initialize connection with device %d\n", dev);

      memset (ip_addr, '\0', 16);
      ip_port = 0;

      ipconf = (__po_hi_c_ip_conf_t*) __po_hi_get_device_configuration (dev);
      ip_port = (int)ipconf->port;

      __DEBUGMSG ("[DRIVER SOCKETS] Configuration for device %d, addr=%s, port=%d\n", dev, ipconf->address, ip_port);

      if (ip_port == 0)
      {
         __DEBUGMSG ("[DRIVER SOCKETS] Invalid remote port\n");
         continue;
      }

      while (1)
      {
         nodes[dev].socket = socket (AF_INET, SOCK_STREAM, 0);

         if (nodes[dev].socket == -1 )
572
         {
573
574
575
            __DEBUGMSG ("[DRIVER SOCKETS] Socket for dev %d is not created\n", dev);
            return;
         }
576

577
         __DEBUGMSG ("[DRIVER SOCKETS] Socket for dev %d created, value=%d\n", dev, nodes[dev].socket);
julien.delange's avatar
julien.delange committed
578

579
         hostinfo = gethostbyname ((char*)ipconf->address);
julien.delange's avatar
julien.delange committed
580

581
582
583
584
         if (hostinfo == NULL )
         {
            __DEBUGMSG ("[DRIVER SOCKETS] Error while getting host informations for device %d\n", dev);
         }
585

586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
         sa.sin_port = htons (ip_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];
         }
604

605
606
607
608
609
         /*
          * We try to connect on the remote host. We try every
          * second to connect on.
         __PO_HI_SET_SOCKET_TIMEOUT(nodes[dev].socket,5);
          */
610

611
612
613
         ret = connect (nodes[dev].socket, 
                        (struct sockaddr*) &sa ,
                        sizeof (struct sockaddr_in));
julien.delange's avatar
julien.delange committed
614

615
616
617
618
619
620
621
622
623
624
625
626
627
#ifdef __PO_HI_USE_PROTOCOL_MYPROTOCOL_I
         if (ret == 0)
         {
            __DEBUGMSG ("[DRIVER SOCKETS] Connection established with device %d, socket=%d\n", dev, nodes[dev].socket);

            break;
         }
         else
         {
            __DEBUGMSG ("connect() failed, return=%d\n", ret);
         }

#else
628
629
         if (ret == 0)
         {
julien.delange's avatar
julien.delange committed
630

631
632
            __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))
julien.delange's avatar
julien.delange committed
633
            {
634
               __DEBUGMSG ("[DRIVER SOCKETS] Device %d cannot send his id\n", id);
julien.delange's avatar
julien.delange committed
635
            }
636
637
638
639
640
641
642
            __DEBUGMSG ("[DRIVER SOCKETS] Connection established with device %d, socket=%d\n", dev, nodes[dev].socket);
            break;
         }
         else
         {
            __DEBUGMSG ("connect() failed, return=%d\n", ret);
         }
643
#endif
julien.delange's avatar
julien.delange committed
644

645
646
647
         if (close (nodes[dev].socket))
         {
            __DEBUGMSG ("[DRIVER SOCKETS] Cannot close socket %d\n", nodes[dev].socket);
648
         }
julien.delange's avatar
julien.delange committed
649

650
651
652
653
         /*
          * We wait 500ms each time we try to connect on the
          * remote host
          */
654

655
656
657
         __po_hi_get_time (&current_time);
         __po_hi_milliseconds (&tmptime, 500);
         __po_hi_add_times (&mytime, &current_time, &tmptime);
658
         __DEBUGMSG ("[DRIVER SOCKETS] Cannot connect on device %d, wait 500ms\n", dev);
659
         __po_hi_delay_until (&mytime);
660
661
      }
   }
662

663
}
664

665
666
#endif