Jelajahi Sumber

made OpENer compile able with c++, updated porting guide to include ref to setDeviceSerial

Alois Zoitl 16 tahun lalu
induk
melakukan
5622ecbe82

+ 0 - 1
bin/pc/Makefile

@@ -10,7 +10,6 @@ TERSE=1			# error and connection up/down messages only
 VERBOSE=2		# running commentary
 VVERBOSE=3		# commentary plus message dumps
 
-
 CFLAGS= \
 	-g \
 	-I . \

+ 2 - 2
src/cip/cipassembly.c

@@ -47,7 +47,7 @@ S_CIP_Instance *createAssemblyObject(EIP_UINT8 pa_nInstanceID,
 
     pstAssemblyInstance = addCIPInstance(pstAssemblyClass, pa_nInstanceID); /* add instances (always succeeds (or asserts))*/
 
-    if ((stAssemblyByteArray = IApp_CipCalloc(1, sizeof(S_CIP_Byte_Array))) == 0)
+    if ((stAssemblyByteArray = (S_CIP_Byte_Array *)IApp_CipCalloc(1, sizeof(S_CIP_Byte_Array))) == 0)
       {
         return 0; /*TODO remove assembly instance in case of error*/
       }
@@ -66,7 +66,7 @@ EIP_STATUS notifyAssemblyConnectedDataReceived(S_CIP_Instance * pa_pstInstance,
     
     /* empty path (path size = 0) need to be checked and taken care of in future */
     /* copy received data to Attribute 3 */
-    p = pa_pstInstance->pstAttributes->pt2data;
+    p = (S_CIP_Byte_Array *)pa_pstInstance->pstAttributes->pt2data;
     if (p->len < pa_nDataLength)
       {
         if (EIP_DEBUG>EIP_VERBOSE)

+ 17 - 16
src/cip/cipcommon.c

@@ -127,7 +127,7 @@ S_CIP_Instance *addCIPInstances(S_CIP_Class * pa_pstCIPClass,  int pa_nNr_of_Ins
         inst++; /*    keep track of what the first new instance number will be */
       }
 
-    first = p = IApp_CipCalloc(pa_nNr_of_Instances, sizeof(S_CIP_Instance)); /* allocate a block of memory for all created instances*/
+    first = p = (S_CIP_Instance *) IApp_CipCalloc(pa_nNr_of_Instances, sizeof(S_CIP_Instance)); /* allocate a block of memory for all created instances*/
     assert(p);
     /* fail if run out of memory */
 
@@ -142,7 +142,7 @@ S_CIP_Instance *addCIPInstances(S_CIP_Class * pa_pstCIPClass,  int pa_nNr_of_Ins
 
         if (pa_pstCIPClass->nNr_of_Attributes) /* if the class calls for instance attributes */
           { /* then allocate storage for the attribute array */
-            p->pstAttributes = IApp_CipCalloc(
+            p->pstAttributes = (S_CIP_attribute_struct*)IApp_CipCalloc(
                 pa_pstCIPClass->nNr_of_Attributes,
                 sizeof(S_CIP_attribute_struct));
           }
@@ -189,8 +189,8 @@ S_CIP_Class *createCIPClass(EIP_UINT32 pa_nClassID,
      and contains a pointer to a metaclass
      CIP never explicitly addresses a metaclass*/
 
-    pt2Class = IApp_CipCalloc(1, sizeof(S_CIP_Class)); /* create the class object*/
-    pt2MetaClass = IApp_CipCalloc(1, sizeof(S_CIP_Class)); /* create the metaclass object*/
+    pt2Class = (S_CIP_Class*)IApp_CipCalloc(1, sizeof(S_CIP_Class)); /* create the class object*/
+    pt2MetaClass = (S_CIP_Class*)IApp_CipCalloc(1, sizeof(S_CIP_Class)); /* create the metaclass object*/
 
     /* initialize the class-specific fields of the Class struct*/
     pt2Class->nClassID = pa_nClassID; /* the class remembers the class ID */
@@ -209,7 +209,7 @@ S_CIP_Class *createCIPClass(EIP_UINT32 pa_nClassID,
     pt2MetaClass->nGetAttrAllMask = pa_nClassGetAttrAllMask; /* indicate which attributes are included in class getAttributeAll*/
     pt2MetaClass->nNr_of_Services = pa_nNr_of_ClassServices+2; /* the metaclass manages the behavior of the class itself */
     pt2Class->pstServices = 0; 
-    pt2MetaClass->acName = IApp_CipCalloc(1, strlen(pa_acName)+6); /* fabricate the name "meta<classname>"*/
+    pt2MetaClass->acName = (char *)IApp_CipCalloc(1, strlen(pa_acName)+6); /* fabricate the name "meta<classname>"*/
     strcpy(pt2MetaClass->acName, "meta-");
     strcat(pt2MetaClass->acName, pa_acName);
 
@@ -227,14 +227,14 @@ S_CIP_Class *createCIPClass(EIP_UINT32 pa_nClassID,
 
     /* further initialization of the class object*/
 
-    pt2Class->pstAttributes = IApp_CipCalloc(pa_nNr_of_ClassAttributes+5,
+    pt2Class->pstAttributes = (S_CIP_attribute_struct *)IApp_CipCalloc(pa_nNr_of_ClassAttributes+5,
         sizeof(S_CIP_attribute_struct));
     /* TODO -- check that we didn't run out of memory?*/
 
-    pt2MetaClass->pstServices = IApp_CipCalloc(pa_nNr_of_ClassServices+2,
+    pt2MetaClass->pstServices = (S_CIP_service_struct *)IApp_CipCalloc(pa_nNr_of_ClassServices+2,
         sizeof(S_CIP_service_struct));
 
-    pt2Class->pstServices = IApp_CipCalloc(pa_nNr_of_InstanceServices+2,
+    pt2Class->pstServices = (S_CIP_service_struct *)IApp_CipCalloc(pa_nNr_of_InstanceServices+2,
         sizeof(S_CIP_service_struct));
 
     if (pa_nNr_of_Instances > 0)
@@ -312,7 +312,7 @@ void insertService(S_CIP_Class * pa_pClass,  EIP_UINT8 pa_nServiceNr,
     p = pa_pClass->pstServices; /* get a pointer to the service array*/
     assert(p!=0);
     /* adding a service to a class that was not declared to have services is not allowed*/
-    for (i = 0; i < pa_pClass->nNr_of_Services; i++) /* interate over all service slots attached to the class */
+    for (i = 0; i < pa_pClass->nNr_of_Services; i++) /* Iterate over all service slots attached to the class */
       {
         if (p->CIP_ServiceNr == pa_nServiceNr || p->m_ptfuncService == 0) /* found undefined service slot*/
           {
@@ -413,9 +413,10 @@ int outputAttribute(S_CIP_attribute_struct *pa_ptstAttribute,
     case (CIP_DATE):
     case (CIP_TIME_OF_DAY):
     case (CIP_DATE_AND_TIME):
+        break;
     case (CIP_STRING):
       {
-        S_CIP_String *s = pa_ptstAttribute->pt2data;
+        S_CIP_String *s = (S_CIP_String *)pa_ptstAttribute->pt2data;
 
         htols(*(EIP_UINT16 *) &(s->Length), &pa_pnMsg);
         for (j = 0; j < s->Length; j++)
@@ -440,7 +441,7 @@ int outputAttribute(S_CIP_attribute_struct *pa_ptstAttribute,
 
     case (CIP_SHORT_STRING):
       {
-        S_CIP_Short_String *ss = pa_ptstAttribute->pt2data;
+        S_CIP_Short_String *ss = (S_CIP_Short_String *)pa_ptstAttribute->pt2data;
 
         *pa_pnMsg++ = ss->Length;
         for (j = 0; j < ss->Length; j++)
@@ -456,7 +457,7 @@ int outputAttribute(S_CIP_attribute_struct *pa_ptstAttribute,
 
     case (CIP_EPATH):
       {
-        EIP_UINT16 *p = pa_ptstAttribute->pt2data;
+        EIP_UINT16 *p = (EIP_UINT16 *)pa_ptstAttribute->pt2data;
         EIP_UINT16 len;
         EIP_UINT16 data;
 
@@ -477,7 +478,7 @@ int outputAttribute(S_CIP_attribute_struct *pa_ptstAttribute,
 
     case (CIP_USINT_USINT):
       {
-        S_CIP_Revision *rv = pa_ptstAttribute->pt2data;
+        S_CIP_Revision *rv = (S_CIP_Revision *)pa_ptstAttribute->pt2data;
 
         *pa_pnMsg++ = rv->MajorRevision;
         *pa_pnMsg++ = rv->MinorRevision;
@@ -487,7 +488,7 @@ int outputAttribute(S_CIP_attribute_struct *pa_ptstAttribute,
 
     case (CIP_UDINT_UDINT_UDINT_UDINT_UDINT_STRING):
       {
-        EIP_UINT32 *p = pa_ptstAttribute->pt2data;
+        EIP_UINT32 *p = (EIP_UINT32 *)pa_ptstAttribute->pt2data;
         S_CIP_String *s;
 
         htoll(p[0], &pa_pnMsg);
@@ -517,7 +518,7 @@ int outputAttribute(S_CIP_attribute_struct *pa_ptstAttribute,
 
     case (CIP_6USINT):
       {
-        EIP_UINT8 *p = pa_ptstAttribute->pt2data;
+        EIP_UINT8 *p = (EIP_UINT8 *)pa_ptstAttribute->pt2data;
 
         for (j = 0; j < 6; j++)
           {
@@ -535,7 +536,7 @@ int outputAttribute(S_CIP_attribute_struct *pa_ptstAttribute,
 
     case (INTERNAL_UINT16_6): /* TODO for port class attribute 9, hopefully we can find a better way to do this*/
       { 
-        EIP_UINT16 *p = pa_ptstAttribute->pt2data;
+        EIP_UINT16 *p = (EIP_UINT16 *)pa_ptstAttribute->pt2data;
 
         htols(p[0], &pa_pnMsg);
         htols(p[1], &pa_pnMsg);

+ 7 - 7
src/cip/cipconnectionmanager.c

@@ -136,22 +136,22 @@ EIP_STATUS OpenMulticastConnection(int pa_direction,
 EIP_STATUS OpenConsumingPointToPointConnection(
     S_CIP_ConnectionObject *pa_pstConnObj, S_CIP_CPF_Data *pa_CPF_data);
 
-EIP_STATUS OpenProducingPointToPointConnection(
+int OpenProducingPointToPointConnection(
     S_CIP_ConnectionObject *pa_pstConnObj, S_CIP_CPF_Data *pa_CPF_data,
     EIP_UINT16 *pa_pnExtendedError);
 
 /** \brief check if the data given in the connection object match with an already established connection
  * 
- * The comparision is done according to the definitions in the CIP spec Section 3-5.5.2:
+ * The comparison is done according to the definitions in the CIP specification Section 3-5.5.2:
  * The following elements have to be equal: Vendor ID, Connection Serial Number, Originator Serial Number
- * @param pa_pstConnObj connection object containing the comparision elements from the forward open request
+ * @param pa_pstConnObj connection object containing the comparison elements from the forward open request
  * @return 
  *    - -1 if no equal established connection exists
- *    - the index number of the queal connection object       
+ *    - the index number of the equal connection object
  */
 int checkForExistingConnection(S_CIP_ConnectionObject *pa_pstConnObj);
 
-/** \brief Compare the electronic key recieved with a forward open request with the device's data.
+/** \brief Compare the electronic key received with a forward open request with the device's data.
  * 
  * @param pa_nKeyFormat format identifier given in the forward open request
  * @param pa_pstKeyData pointer to the electronic key data recieved in the forward open request
@@ -542,7 +542,7 @@ EIP_STATUS OpenConsumingPointToPointConnection(
     return EIP_OK;
   }
 
-EIP_STATUS OpenProducingPointToPointConnection(
+int OpenProducingPointToPointConnection(
     S_CIP_ConnectionObject *pa_pstConnObj, S_CIP_CPF_Data *pa_CPF_data,
     EIP_UINT16 *pa_pnExtendedError)
   {
@@ -1544,7 +1544,7 @@ EIP_STATUS sendConnectedData(S_CIP_ConnectionObject *pa_pstConnection)
 
     pCPFDataItem->stDataI_Item.TypeID = CIP_ITEM_ID_CONNECTIONTRANSPORTPACKET;
 
-    p = pa_pstConnection->p_stProducingInstance->pstAttributes->pt2data;
+    p = (S_CIP_Byte_Array *) pa_pstConnection->p_stProducingInstance->pstAttributes->pt2data;
     pCPFDataItem->stDataI_Item.Length = 0;
 
     /* notify the application that data will be sent immediately after the call */

+ 8 - 10
src/cip/cipmessagerouter.c

@@ -131,7 +131,7 @@ EIP_STATUS registerClass(S_CIP_Class * pa_pt2Class)
     while (*p)
       p = &(*p)->next; /* follow the list until p points to an empty link (list end)*/
 
-    *p = IApp_CipCalloc(1, sizeof(S_CIP_MR_Object)); /* create a new node at the end of the list*/
+    *p = (S_CIP_MR_Object *)IApp_CipCalloc(1, sizeof(S_CIP_MR_Object)); /* create a new node at the end of the list*/
     if (*p == 0)
       return EIP_ERROR; /* check for memory error*/
 
@@ -140,8 +140,10 @@ EIP_STATUS registerClass(S_CIP_Class * pa_pt2Class)
     return EIP_OK;
   }
 
-int notifyMR(EIP_UINT8 * pa_pnData, int pa_nDataLength)
+EIP_STATUS notifyMR(EIP_UINT8 * pa_pnData, int pa_nDataLength)
   {
+    EIP_STATUS nRetVal = EIP_OK;
+
     EIP_BYTE nStatus;
     if (EIP_DEBUG>=EIP_VERBOSE)
       printf("notifyMR: routing unconnected message\n");
@@ -155,7 +157,6 @@ int notifyMR(EIP_UINT8 * pa_pnData, int pa_nDataLength)
         gMRResponse.Reserved = 0;
         gMRResponse.DataLength = 0;
         gMRResponse.ReplyService = (0x80 | gMRRequest.Service);
-        return 0;
       }
     else
       {
@@ -174,30 +175,27 @@ int notifyMR(EIP_UINT8 * pa_pnData, int pa_nDataLength)
             gMRResponse.Reserved = 0;
             gMRResponse.DataLength = 0;
             gMRResponse.ReplyService = (0x80 | gMRRequest.Service);
-            return 0;
           }
         else
           {
             /* call notify function from Object with ClassID (gMRRequest.RequestPath.ClassID)
              object will or will not make an reply into gMRResponse*/
-            EIP_STATUS status;
-
             gMRResponse.Reserved = 0;
             assert(pt2regObject->pt2Class);
             if (EIP_DEBUG>=EIP_VERBOSE)
               printf("notifyMR: calling notify function of class '%s'\n",
                   pt2regObject->pt2Class->acName);
-            status = notifyClass(pt2regObject->pt2Class, &gMRRequest,
+            nRetVal = notifyClass(pt2regObject->pt2Class, &gMRRequest,
                 &gMRResponse);
 
             if (EIP_DEBUG<EIP_VERBOSE)
               {
               }
-            else if (status == -1)
+            else if (nRetVal == EIP_ERROR)
               printf(
                   "notifyMR: notify function of class '%s' returned an error\n",
                   pt2regObject->pt2Class->acName);
-            else if (status == 0)
+            else if (nRetVal == EIP_OK)
               printf(
                   "notifyMR: notify function of class '%s' returned no reply\n",
                   pt2regObject->pt2Class->acName);
@@ -205,9 +203,9 @@ int notifyMR(EIP_UINT8 * pa_pnData, int pa_nDataLength)
               printf(
                   "notifyMR: notify function of class '%s' returned a reply\n",
                   pt2regObject->pt2Class->acName);
-            return status;
           }
       }
+    return nRetVal;
   }
 
 EIP_BYTE createMRRequeststructure(EIP_UINT8 * pa_pnData, EIP_INT16 pa_nLength, S_CIP_MR_Request * pa_pstMRReqdata)

+ 1 - 1
src/cip/cipmessagerouter.h

@@ -35,7 +35,7 @@ EIP_STATUS CIP_MessageRouter_Init(void);
  *  @return  EIP_ERROR on fault
  *           EIP_OK on success           
  */ 
-int notifyMR(EIP_UINT8 *pa_pnData, int pa_nDataLength); 
+EIP_STATUS notifyMR(EIP_UINT8 *pa_pnData, int pa_nDataLength);
 
 /*! Register a class at the message router.
  *  In order that the message router can deliver

+ 2 - 2
src/cip/ciptcpipinterface.c

@@ -73,7 +73,7 @@ void configureDomainName(const char *pa_acDomainName)
     Interface_Configuration.DomainName.Length = strlen(pa_acDomainName);
     if (Interface_Configuration.DomainName.Length)
       {
-        Interface_Configuration.DomainName.String = calloc(
+        Interface_Configuration.DomainName.String = (EIP_INT8 *)IApp_CipCalloc(
             Interface_Configuration.DomainName.Length + 1, sizeof(EIP_INT8));
         strcpy(Interface_Configuration.DomainName.String, pa_acDomainName);
       }
@@ -92,7 +92,7 @@ void configureHostName(const char *pa_acHostName)
     Hostname.Length = strlen(pa_acHostName);
     if (Hostname.Length)
       {
-        Hostname.String = calloc(Hostname.Length + 1, sizeof(EIP_INT8));
+        Hostname.String = (EIP_INT8 *)IApp_CipCalloc(Hostname.Length + 1, sizeof(EIP_INT8));
         strcpy(Hostname.String, pa_acHostName);
       }
     else

+ 12 - 3
src/opener_api.h

@@ -238,10 +238,14 @@ void closeSession(int pa_nSocket);
 /** \ingroup CIP_CALLBACK_API 
  * \brief Callback for the application initialization
  *
- * This function will be called by the CIP stack after it has finished its initialization. In this function the user can setup all CIP objects she likes to have.
- * TODO think if this is still the right way to do this. Maybe just after the CIP_INIT would be fine to. 
+ * This function will be called by the CIP stack after it has finished its
+ * initialization. In this function the user can setup all CIP objects she
+ * likes to have.
  *
- *  return status -1 .. error.
+ * This function is provided for convenience reasons. After the void CIP_Init(void)
+ * function has finished it is okay to also generate your CIP objects.
+ *  return status EIP_ERROR .. error
+ *                EIP_OK ... successful finish
  */
 EIP_STATUS IApp_Init(void);
 
@@ -414,6 +418,11 @@ void IApp_CloseSocket(int pa_nSockFd);
  *       file or from operating system functions. If these values should be 
  *       settable remotely via explicit messages the SetAttributeSingle functions
  *       of the EtherNetLink and the TCPIPInterface object have to be adapted.
+ *   -# Set the device's serial number\n
+ *      According to the CIP specification a device vendor has to ensure that
+ *      each of its devices has a unique 32Bit device id. You can set it with
+ *      the function:
+ *       - void setDeviceSerialNumber(EIP_UINT32 pa_nSerialNumber)
  *   -# Initialize OpENer: \n
  *      With the function CIP_Init(void) the internal data structures of opener are 
  *      correctly setup. After this step own CIP objects and Assembly objects 

+ 2 - 2
src/ports/platform-pc/main.c

@@ -30,8 +30,8 @@ int main(int argc, char *arg[])
     EIP_UINT8 acMyMACAddress[6];
 
     if (argc != 12)
-      { printf("Wrong number of commandline parameters!\n");
-        printf("The correct commandline parameters are:\n"); 
+      { printf("Wrong number of command line parameters!\n");
+        printf("The correct command line parameters are:\n");
         printf("./opener ipaddress subnetmask gateway domainname hostaddress macaddress\n");
         printf("    e.g. ./opener 192.168.0.2 255.255.255.0 192.168.0.1 test.com testdevice 00 15 C5 BF D0 87\n");      
         exit(0);

+ 426 - 407
src/ports/platform-pc/networkhandler.c

@@ -19,15 +19,14 @@
 #include <cipconnectionmanager.h>
 #include <endianconv.h> 
 
-
 EIP_UINT8 g_acCommBuf[OPENER_ETHERNET_BUFFER_SIZE];
 
-extern void dump(unsigned char *p, int size);
+extern void
+dump(unsigned char *p, int size);
 
 #define MAX_NO_OF_TCP_SOCKETS 10
 
 typedef long MILLISECONDS;
-
 fd_set master;
 fd_set read_fds;
 /* temporary file discriptor for select() */
@@ -39,40 +38,41 @@ int newfd;
 static struct timeval tv;
 static MILLISECONDS actualtime, lasttime;
 
+EIP_STATUS
+handleDataOnTCPSocket(int pa_nSocket);
 
-EIP_STATUS handleDataOnTCPSocket(int pa_nSocket);
-
-
-static MILLISECONDS getmilliseconds(void)
-  {
-    struct timeval tv;
+static MILLISECONDS
+getmilliseconds(void)
+{
+  struct timeval tv;
 
-    gettimeofday(&tv, 0);
-    return (MILLISECONDS)tv.tv_sec * 1000 + (MILLISECONDS)tv.tv_usec / 1000;
-  }
+  gettimeofday(&tv, 0);
+  return (MILLISECONDS) tv.tv_sec * 1000 + (MILLISECONDS) tv.tv_usec / 1000;
+}
 
 /*! Check if the socket indentifier is associate with an active connection
  * 
  *  @param pa_nFD  socket handle
  *  @return 1 if the given socket handler is of an active conneciton otherwise 0
  */
-int isConnectedFd(int pa_nFD)
-  {
-    int i;
-    extern S_CIP_ConnectionObject stConnectionObject[];
-
-    S_CIP_ConnectionObject *con = &stConnectionObject[0]; /* this is done this way because the debugger would not display the connection table */
-
-    for (i = 0; i < OPENER_NUMBER_OF_SUPPORTED_CONNECTIONS; i++)
-      {
-        if ((stConnectionObject[i].sockfd[0] == pa_nFD)
-            || (stConnectionObject[i].sockfd[1] == pa_nFD))
-          {
-            return 1;
-          }
-      }
-    return 0;
-  }
+int
+isConnectedFd(int pa_nFD)
+{
+  int i;
+  extern S_CIP_ConnectionObject stConnectionObject[];
+
+  S_CIP_ConnectionObject *con = &stConnectionObject[0]; /* this is done this way because the debugger would not display the connection table */
+
+  for (i = 0; i < OPENER_NUMBER_OF_SUPPORTED_CONNECTIONS; i++)
+    {
+      if ((stConnectionObject[i].sockfd[0] == pa_nFD)
+          || (stConnectionObject[i].sockfd[1] == pa_nFD))
+        {
+          return 1;
+        }
+    }
+  return 0;
+}
 
 /* INT8 Start_NetworkHandler()
  * 	start a TCP listening socket, accept connections, receive data in select loop, call manageConnections periodicaly.
@@ -80,393 +80,412 @@ int isConnectedFd(int pa_nFD)
  * 			-1 .. error
  */
 
-EIP_STATUS Start_NetworkHandler()
-  {
-    struct sockaddr_in remote_addr, from;
-    struct sockaddr_in my_addr;
-    socklen_t addrlen;
-    socklen_t fromlen = sizeof(from);
-    int nUDPListener;
-
-    int nReceived_size;
-    int res;
-    MILLISECONDS elapsedtime = 0;
-    int fd;
-    EIP_UINT8 *rxp;
-    int nRemainingBytes;
-    int replylen;
-
-    /* clear the master an temp sets */
-    FD_ZERO(&master);
-    FD_ZERO(&read_fds);
-
-    /* create a new TCP socket */
-    if ((listener = socket(PF_INET,SOCK_STREAM, 0)) == -1)
-      {
-        printf("error allocating socket stream listener, %d\n", errno);
-        return EIP_ERROR;
-      }
-
-    /* create a new UDP socket */
-    if ((nUDPListener = socket(PF_INET,SOCK_DGRAM, 0)) == -1)
-      {
-        printf("error allocating udp listener socket, %d\n", errno);
-        return EIP_ERROR;
-      }
-
-    my_addr.sin_family = AF_INET;
-    my_addr.sin_port = htons(OPENER_ETHERNET_PORT);
-    my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
-    memset(&my_addr.sin_zero, 0, sizeof(my_addr.sin_zero));
-
-    /* bind the new socket to port 0xAF12 (CIP) */
-    if ((bind(listener, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)))
-        == -1)
-      {
-        perror("error with bind");
-        return EIP_ERROR;
-      }
-    
-    /* enable the udp socket to receive broadcast messages*/
-    int y = 1;
-    if (0 > setsockopt(nUDPListener, SOL_SOCKET, SO_BROADCAST, &y, sizeof(int)))
-      {
-        perror("error with setting broadcast receive for udp socket");
-        return EIP_ERROR;
-      }
-    
-    if ((bind(nUDPListener, (struct sockaddr *) &my_addr,
-        sizeof(struct sockaddr))) == -1)
-      {
-        perror("error with udp bind");
-        return EIP_ERROR;
-      }
-
-    /* switch socket in listen mode */
-    if ((listen(listener, MAX_NO_OF_TCP_SOCKETS)) == -1)
-      {
-        perror("networkhandler: error with listen");
-        return EIP_ERROR;
-      }
-
-    /* add the listener socket to the master set */
-    FD_SET(listener, &master);
-    FD_SET(nUDPListener, &master);
-
-    /* keep track of the biggest file discriptor */
-    fdmax = (listener > nUDPListener) ? listener : nUDPListener;
-
-    lasttime = getmilliseconds(); /* init timekeeping */
-    elapsedtime = 0;
-
-    while (1)
-      {
-        read_fds = master;
-
-        tv.tv_sec = 0;
-        tv.tv_usec = (elapsedtime < OPENER_TIMER_TICK ? OPENER_TIMER_TICK - elapsedtime : 0)
-            * 1000; /* 10 ms */
-
-        res = select(fdmax + 1, &read_fds, 0, 0, &tv);
-        if (res == -1)
-          {
-            perror("networkhandler: error with select");
-            return EIP_ERROR;
-          }
-
-        if (res > 0)
-          for (fd = 0; fd <= fdmax; fd++)
+EIP_STATUS
+Start_NetworkHandler()
+{
+  struct sockaddr_in remote_addr, from;
+  struct sockaddr_in my_addr;
+  socklen_t addrlen;
+  socklen_t fromlen = sizeof(from);
+  int nUDPListener;
+
+  int nReceived_size;
+  int res;
+  MILLISECONDS elapsedtime = 0;
+  int fd;
+  EIP_UINT8 *rxp;
+  int nRemainingBytes;
+  int replylen;
+
+  /* clear the master an temp sets */
+  FD_ZERO(&master);
+  FD_ZERO(&read_fds);
+
+  /* create a new TCP socket */
+  if ((listener = socket(PF_INET, SOCK_STREAM, 0)) == -1)
+    {
+      printf("error allocating socket stream listener, %d\n", errno);
+      return EIP_ERROR;
+    }
+
+  /* create a new UDP socket */
+  if ((nUDPListener = socket(PF_INET, SOCK_DGRAM, 0)) == -1)
+    {
+      printf("error allocating udp listener socket, %d\n", errno);
+      return EIP_ERROR;
+    }
+
+  my_addr.sin_family = AF_INET;
+  my_addr.sin_port = htons(OPENER_ETHERNET_PORT);
+  my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
+  memset(&my_addr.sin_zero, 0, sizeof(my_addr.sin_zero));
+
+  /* bind the new socket to port 0xAF12 (CIP) */
+  if ((bind(listener, (struct sockaddr *) &my_addr, sizeof(struct sockaddr)))
+      == -1)
+    {
+      perror("error with bind");
+      return EIP_ERROR;
+    }
+
+  /* enable the udp socket to receive broadcast messages*/
+  int y = 1;
+  if (0 > setsockopt(nUDPListener, SOL_SOCKET, SO_BROADCAST, &y, sizeof(int)))
+    {
+      perror("error with setting broadcast receive for udp socket");
+      return EIP_ERROR;
+    }
+
+  if ((bind(nUDPListener, (struct sockaddr *) &my_addr, sizeof(struct sockaddr)))
+      == -1)
+    {
+      perror("error with udp bind");
+      return EIP_ERROR;
+    }
+
+  /* switch socket in listen mode */
+  if ((listen(listener, MAX_NO_OF_TCP_SOCKETS)) == -1)
+    {
+      perror("networkhandler: error with listen");
+      return EIP_ERROR;
+    }
+
+  /* add the listener socket to the master set */
+  FD_SET(listener, &master);
+  FD_SET(nUDPListener, &master);
+
+  /* keep track of the biggest file discriptor */
+  fdmax = (listener > nUDPListener) ? listener : nUDPListener;
+
+  lasttime = getmilliseconds(); /* init timekeeping */
+  elapsedtime = 0;
+
+  while (1)
+    {
+      read_fds = master;
+
+      tv.tv_sec = 0;
+      tv.tv_usec = (elapsedtime < OPENER_TIMER_TICK ? OPENER_TIMER_TICK
+          - elapsedtime : 0) * 1000; /* 10 ms */
+
+      res = select(fdmax + 1, &read_fds, 0, 0, &tv);
+      if (res == -1)
+        {
+          if (EINTR == errno)
             {
-              if (FD_ISSET(fd, &read_fds))
-                {
-                  if (!FD_ISSET(fd, &master))
-                    {
-                      printf("socket fd %d closed with pending message\n", fd);
-                      continue;
-                    }
-
-                  /* see if this is a connection request to the TCP listener*/
-                  if (fd == listener) /* handle new TCP connection */
-                    {
-                      if (EIP_DEBUG >= EIP_VERBOSE)
-                        printf("networkhandler: new TCP connection\n");
-                      addrlen = sizeof(remote_addr);
-                      newfd = accept(listener, (struct sockaddr *)&remote_addr,
-                          &addrlen); /* remote_addr does not seem to be used*/
-                      if (newfd == -1)
-                        {
-                          perror("networkhandler: error on accept");
-                          continue;
-                        }
-
-                      FD_SET(newfd, &master);
-                      /* add newfd to master set */
-                      if (newfd > fdmax)
-                        fdmax = newfd;
-                      if (EIP_DEBUG >= EIP_VERBOSE)
-                        printf(
-                            "networkhandler: opened new TCP connection on fd %d\n",
-                            newfd);
-                      continue;
-                    }
-
-                  /* see if this is an unsolicited inbound UDP message */
-                  if (fd == nUDPListener)
-                    {
-                      if (EIP_DEBUG >= EIP_VERBOSE)
-                        printf(
-                            "networkhandler: unsolicited UDP message on fd %d\n",
-                            fd);
-
-                      /*Handle udp broadcast messages */
-                      nReceived_size = recvfrom(fd, g_acCommBuf,
-                          OPENER_ETHERNET_BUFFER_SIZE, 0, (struct sockaddr *)&from,
-                          &fromlen);
-
-                      if (nReceived_size <= 0)
-                        { /* got error */
-                          perror("networkhandler: error on recvfrom udp broadcast port");
-                          continue;
-                        }
-
-                      if (EIP_DEBUG >= EIP_VVERBOSE)
-                        {
-                          printf("Data received on udp:\n");
-                          dump(g_acCommBuf, nReceived_size);
-                        }
-
-                      rxp = &g_acCommBuf[0];
-                      do
-                        {
-                          replylen = handleReceivedExplictData(fd, rxp, nReceived_size,
-                              &nRemainingBytes);
-
-                          rxp += nReceived_size - nRemainingBytes;
-                          nReceived_size = nRemainingBytes;
-
-                          if (replylen > 0)
-                            {
-                              if (EIP_DEBUG >= EIP_VVERBOSE)
-                                {
-                                  printf("reply sent:\n");
-                                  dump(g_acCommBuf, replylen);
-                                }
-
-                              /* if the active fd matches a registered UDP callback, handle a UDP packet */
-                              res = sendto(fd, (char *)g_acCommBuf, replylen,
-                                  0, (struct sockaddr *)&from, sizeof(from));
-                              if (res != replylen)
-                                {
-                                  printf("networkhandler: UDP response was not fully sent\n");
-                                }
-                            }
-                        } while (nRemainingBytes > 0);
-                      continue;
-                    }
-
-                  /* see if the message is from a registered UDP socket */
-                  if (isConnectedFd(fd))
-                    {
-                      fromlen = sizeof(from);
-                      nReceived_size = recvfrom(fd, g_acCommBuf, 
-                          OPENER_ETHERNET_BUFFER_SIZE, 0, (struct sockaddr *)&from, &fromlen);
-                      if (nReceived_size == 0)
-                        {
-                          printf("connection closed by client\n");
-                          FD_CLR(fd, &master);
-                          /* remove from master set */
-                          close(fd); /* close socket */
-                          continue;
-                        }
-                      if (nReceived_size <= 0)
-                        {
-                          perror("networkhandler: error on recv");
-                          FD_CLR(fd, &master);
-                          /* remove from master set */
-                          close(fd); /* close socket */
-                          continue;
-                        }
-
-                      handleReceivedConnectedData(g_acCommBuf, nReceived_size);
-                      continue;
-                    }
-
-                  /* if not registered UDP, handle as a TCP receive */
-                  if (EIP_ERROR == handleDataOnTCPSocket(fd)) /* if error */
-                    {
-                      FD_CLR(fd, &master);
-                      /* remove connection from master set */
-                      closeSession(fd); /* clean up session and close the socket */
-                    }
-                }
+              /* we have somehow been interrupted. The default behavior is to
+               * go back into the select loop.
+               */
+              continue;
             }
+          else
+            {
+              perror("networkhandler: error with select");
+              return EIP_ERROR;
+            }
+        }
 
-        actualtime = getmilliseconds();
-        elapsedtime += actualtime - lasttime;
-        lasttime = actualtime;
-
-        /* check if we had been not able to update the connection manager for several OPENER_TIMER_TICK.
-         * This should compensate the jitter of the windows timer
-         */
-        while(elapsedtime >= OPENER_TIMER_TICK)
-          {
-            /* call manage_connections() in connection manager every OPENER_TIMER_TICK ms */
-            manageConnections();              
-            elapsedtime -= OPENER_TIMER_TICK; 
-          }  
-      }
-  }
-
-EIP_STATUS IApp_SendUDPData(struct sockaddr_in *pa_pstAddr, int pa_nSockFd,
-    EIP_UINT8 *pa_acData, EIP_UINT16 pa_nDataLength)
-  {
-    int sentlength;
-
-    sentlength = sendto(pa_nSockFd, (char *)pa_acData, pa_nDataLength, 0,
-        (struct sockaddr *)pa_pstAddr, sizeof(*pa_pstAddr));
-
-    if (sentlength < 0)
-      {
-        perror("networkhandler: error with sendto in sendUDPData");
-        return EIP_ERROR;
-      }
-    else if (sentlength != pa_nDataLength)
-      {
-        printf("not all data was sent in sendUDPData, sent %d of %d\n",
-            sentlength, pa_nDataLength);
-        return EIP_ERROR;
-      }
-    else
-      return EIP_OK;
-  }
-
-EIP_STATUS handleDataOnTCPSocket(int pa_nSocket)
-  {
-    EIP_UINT8 *rxp;
-    int nDataSize;
-    int nDataSent;
-    int nRemainingBytes = 0;
-
-    /* We will handle just one EIP packet here the rest is done by the select 
-     * method which will inform us if more data is available in the socket
-       because of the current implementation of the main loop this may not be 
-       the fastest way and a loop here with a non blocking socket would better 
-       fit*/
-
-    /*Check how many data is here -- read the first four bytes from the connection */
-    nDataSize = recv(pa_nSocket, g_acCommBuf, 4, 0); /*TODO we may have to set the socket to a non blocking socket */
-
-    if (nDataSize == 0)
-      {
-        perror("networkhandler: connection closed by client");
-        return EIP_ERROR;
-      }
-    if (nDataSize < 0)
-      {
-        perror("networkhandler: error on recv");
-        return EIP_ERROR;
-      }
-
-    rxp = &g_acCommBuf[2]; /* at this place EIP stores the data length */
-    nDataSize = ltohs(&rxp) + ENCAPSULATION_HEADER_LENGTH - 4; /* -4 is for the 4 bytes we have already read*/
-    /* (NOTE this advances the buffer pointer) */
-    if (OPENER_ETHERNET_BUFFER_SIZE < nDataSize)
-      { /*TODO can this be handled in a better way?*/
-        printf("too large packet recieved will be ignored\n"); /* this may corrupt the connection ???*/
-        return EIP_OK;
-      }
-
-    nDataSize = recv(pa_nSocket, &g_acCommBuf[4], nDataSize, 0);
-
-    if (nDataSize == 0) /* got error or connection closed by client */
-      {
-        perror("networkhandler: connection closed by client");
-        return EIP_ERROR;
-      }
-    if (nDataSize < 0)
-      {
-        perror("networkhandler: error on recv");
-        return EIP_ERROR;
-      }
-
-    nDataSize += 4;
-    /*TODO handle partial packets*/
-    if (EIP_DEBUG> EIP_VVERBOSE)
-      {
-        printf("Data received on tcp:\n");
-        dump(g_acCommBuf, nDataSize);
-      }
-
-    nDataSize = handleReceivedExplictData(pa_nSocket, g_acCommBuf, nDataSize,
-        &nRemainingBytes);
-    if (nRemainingBytes != 0)
-      {
-        if (EIP_DEBUG >= EIP_TERSE)
-          printf("Warning: received packet was to long: %d Bytes left!\n",
-              nRemainingBytes);
-      }
-
-    if (nDataSize > 0)
-      {
-        if (EIP_DEBUG >= EIP_VVERBOSE)
-          {
-            printf("reply sent:\n");
-            dump(g_acCommBuf, nDataSize);
-          }
-
-        nDataSent = send(pa_nSocket, (char *)g_acCommBuf, nDataSize, 0);
-        if (nDataSent != nDataSize)
+      if (res > 0)
+        for (fd = 0; fd <= fdmax; fd++)
           {
-            if (EIP_DEBUG >= EIP_TERSE)
+            if (FD_ISSET(fd, &read_fds))
               {
-                printf("TCP response was not fully sent\n");
+                if (!FD_ISSET(fd, &master))
+                  {
+                    printf("socket fd %d closed with pending message\n", fd);
+                    continue;
+                  }
+
+                /* see if this is a connection request to the TCP listener*/
+                if (fd == listener) /* handle new TCP connection */
+                  {
+                    if (EIP_DEBUG >= EIP_VERBOSE)
+                      printf("networkhandler: new TCP connection\n");
+                    addrlen = sizeof(remote_addr);
+                    newfd = accept(listener, (struct sockaddr *) &remote_addr,
+                        &addrlen); /* remote_addr does not seem to be used*/
+                    if (newfd == -1)
+                      {
+                        perror("networkhandler: error on accept");
+                        continue;
+                      }
+
+                    FD_SET(newfd, &master);
+                    /* add newfd to master set */
+                    if (newfd > fdmax)
+                      fdmax = newfd;
+                    if (EIP_DEBUG >= EIP_VERBOSE)
+                      printf(
+                          "networkhandler: opened new TCP connection on fd %d\n",
+                          newfd);
+                    continue;
+                  }
+
+                /* see if this is an unsolicited inbound UDP message */
+                if (fd == nUDPListener)
+                  {
+                    if (EIP_DEBUG >= EIP_VERBOSE)
+                      printf(
+                          "networkhandler: unsolicited UDP message on fd %d\n",
+                          fd);
+
+                    /*Handle udp broadcast messages */
+                    nReceived_size = recvfrom(fd, g_acCommBuf,
+                        OPENER_ETHERNET_BUFFER_SIZE, 0,
+                        (struct sockaddr *) &from, &fromlen);
+
+                    if (nReceived_size <= 0)
+                      { /* got error */
+                        perror(
+                            "networkhandler: error on recvfrom udp broadcast port");
+                        continue;
+                      }
+
+                    if (EIP_DEBUG >= EIP_VVERBOSE)
+                      {
+                        printf("Data received on udp:\n");
+                        dump(g_acCommBuf, nReceived_size);
+                      }
+
+                    rxp = &g_acCommBuf[0];
+                    do
+                      {
+                        replylen = handleReceivedExplictData(fd, rxp,
+                            nReceived_size, &nRemainingBytes);
+
+                        rxp += nReceived_size - nRemainingBytes;
+                        nReceived_size = nRemainingBytes;
+
+                        if (replylen > 0)
+                          {
+                            if (EIP_DEBUG >= EIP_VVERBOSE)
+                              {
+                                printf("reply sent:\n");
+                                dump(g_acCommBuf, replylen);
+                              }
+
+                            /* if the active fd matches a registered UDP callback, handle a UDP packet */
+                            res = sendto(fd, (char *) g_acCommBuf, replylen, 0,
+                                (struct sockaddr *) &from, sizeof(from));
+                            if (res != replylen)
+                              {
+                                printf(
+                                    "networkhandler: UDP response was not fully sent\n");
+                              }
+                          }
+                      }
+                    while (nRemainingBytes > 0);
+                    continue;
+                  }
+
+                /* see if the message is from a registered UDP socket */
+                if (isConnectedFd(fd))
+                  {
+                    fromlen = sizeof(from);
+                    nReceived_size = recvfrom(fd, g_acCommBuf,
+                        OPENER_ETHERNET_BUFFER_SIZE, 0,
+                        (struct sockaddr *) &from, &fromlen);
+                    if (nReceived_size == 0)
+                      {
+                        printf("connection closed by client\n");
+                        FD_CLR(fd, &master);
+                        /* remove from master set */
+                        close(fd); /* close socket */
+                        continue;
+                      }
+                    if (nReceived_size <= 0)
+                      {
+                        perror("networkhandler: error on recv");
+                        FD_CLR(fd, &master);
+                        /* remove from master set */
+                        close(fd); /* close socket */
+                        continue;
+                      }
+
+                    handleReceivedConnectedData(g_acCommBuf, nReceived_size);
+                    continue;
+                  }
+
+                /* if not registered UDP, handle as a TCP receive */
+                if (EIP_ERROR == handleDataOnTCPSocket(fd)) /* if error */
+                  {
+                    FD_CLR(fd, &master);
+                    /* remove connection from master set */
+                    closeSession(fd); /* clean up session and close the socket */
+                  }
               }
           }
-      }
 
+      actualtime = getmilliseconds();
+      elapsedtime += actualtime - lasttime;
+      lasttime = actualtime;
+
+      /* check if we had been not able to update the connection manager for several OPENER_TIMER_TICK.
+       * This should compensate the jitter of the windows timer
+       */
+      while (elapsedtime >= OPENER_TIMER_TICK)
+        {
+          /* call manage_connections() in connection manager every OPENER_TIMER_TICK ms */
+          manageConnections();
+          elapsedtime -= OPENER_TIMER_TICK;
+        }
+    }
+}
+
+EIP_STATUS
+IApp_SendUDPData(struct sockaddr_in *pa_pstAddr, int pa_nSockFd,
+    EIP_UINT8 *pa_acData, EIP_UINT16 pa_nDataLength)
+{
+  int sentlength;
+
+  sentlength = sendto(pa_nSockFd, (char *) pa_acData, pa_nDataLength, 0,
+      (struct sockaddr *) pa_pstAddr, sizeof(*pa_pstAddr));
+
+  if (sentlength < 0)
+    {
+      perror("networkhandler: error with sendto in sendUDPData");
+      return EIP_ERROR;
+    }
+  else if (sentlength != pa_nDataLength)
+    {
+      printf("not all data was sent in sendUDPData, sent %d of %d\n",
+          sentlength, pa_nDataLength);
+      return EIP_ERROR;
+    }
+  else
     return EIP_OK;
-  }
+}
+
+EIP_STATUS
+handleDataOnTCPSocket(int pa_nSocket)
+{
+  EIP_UINT8 *rxp;
+  int nDataSize;
+  int nDataSent;
+  int nRemainingBytes = 0;
+
+  /* We will handle just one EIP packet here the rest is done by the select
+   * method which will inform us if more data is available in the socket
+   because of the current implementation of the main loop this may not be
+   the fastest way and a loop here with a non blocking socket would better
+   fit*/
+
+  /*Check how many data is here -- read the first four bytes from the connection */
+  nDataSize = recv(pa_nSocket, g_acCommBuf, 4, 0); /*TODO we may have to set the socket to a non blocking socket */
+
+  if (nDataSize == 0)
+    {
+      perror("networkhandler: connection closed by client");
+      return EIP_ERROR;
+    }
+  if (nDataSize < 0)
+    {
+      perror("networkhandler: error on recv");
+      return EIP_ERROR;
+    }
+
+  rxp = &g_acCommBuf[2]; /* at this place EIP stores the data length */
+  nDataSize = ltohs(&rxp) + ENCAPSULATION_HEADER_LENGTH - 4; /* -4 is for the 4 bytes we have already read*/
+  /* (NOTE this advances the buffer pointer) */
+  if (OPENER_ETHERNET_BUFFER_SIZE < nDataSize)
+    { /*TODO can this be handled in a better way?*/
+      printf("too large packet recieved will be ignored\n"); /* this may corrupt the connection ???*/
+      return EIP_OK;
+    }
+
+  nDataSize = recv(pa_nSocket, &g_acCommBuf[4], nDataSize, 0);
+
+  if (nDataSize == 0) /* got error or connection closed by client */
+    {
+      perror("networkhandler: connection closed by client");
+      return EIP_ERROR;
+    }
+  if (nDataSize < 0)
+    {
+      perror("networkhandler: error on recv");
+      return EIP_ERROR;
+    }
+
+  nDataSize += 4;
+  /*TODO handle partial packets*/
+  if (EIP_DEBUG > EIP_VVERBOSE)
+    {
+      printf("Data received on tcp:\n");
+      dump(g_acCommBuf, nDataSize);
+    }
+
+  nDataSize = handleReceivedExplictData(pa_nSocket, g_acCommBuf, nDataSize,
+      &nRemainingBytes);
+  if (nRemainingBytes != 0)
+    {
+      if (EIP_DEBUG >= EIP_TERSE)
+        printf("Warning: received packet was to long: %d Bytes left!\n",
+            nRemainingBytes);
+    }
+
+  if (nDataSize > 0)
+    {
+      if (EIP_DEBUG >= EIP_VVERBOSE)
+        {
+          printf("reply sent:\n");
+          dump(g_acCommBuf, nDataSize);
+        }
+
+      nDataSent = send(pa_nSocket, (char *) g_acCommBuf, nDataSize, 0);
+      if (nDataSent != nDataSize)
+        {
+          if (EIP_DEBUG >= EIP_TERSE)
+            {
+              printf("TCP response was not fully sent\n");
+            }
+        }
+    }
+
+  return EIP_OK;
+}
 
 /* create a new UDP socket for the connection manager
  returns the fd if successful, else -1 */
-int IApp_CreateUDPSocket(int pa_nDirection, struct sockaddr_in *pa_pstAddr)
-  {
-    /* create a new UDP socket */
-    if ((newfd = socket(PF_INET,SOCK_DGRAM, 0)) == -1)
-      {
-        printf("networkhandler: cannot create UDP socket\n");
-        return EIP_ERROR;
-      }
-    if (EIP_DEBUG >= EIP_VERBOSE)
-      printf("networkhandler: UDP socket %d\n", newfd);
-
-    /* check if it is sending or receiving */
-    if (pa_nDirection == CONSUMING)
-      { /* bind is only for consuming necessary */
-        if ((bind(newfd, (struct sockaddr *)pa_pstAddr, sizeof(struct sockaddr)))
-            == -1)
-          {
-            printf("error on bind udp\n");
-            return EIP_ERROR;
-          }
-        if (EIP_DEBUG >= EIP_VERBOSE)
-          printf("networkhandler: bind UDP socket %d\n", newfd);
-      }
-
-    /* add new fd to the master list */
-    FD_SET(newfd, &master);
-    if (newfd > fdmax)
-      {
-        fdmax = newfd;
-      }
-    return newfd;
-  }
-
-void IApp_CloseSocket(int pa_nSockFd)
-  {
-    if(EIP_INVALID_SOCKET != pa_nSockFd)
-      {
-        FD_CLR(pa_nSockFd, &master);
-        close(pa_nSockFd);
-      }  
-  }
+int
+IApp_CreateUDPSocket(int pa_nDirection, struct sockaddr_in *pa_pstAddr)
+{
+  /* create a new UDP socket */
+  if ((newfd = socket(PF_INET, SOCK_DGRAM, 0)) == -1)
+    {
+      printf("networkhandler: cannot create UDP socket\n");
+      return EIP_ERROR;
+    }
+  if (EIP_DEBUG >= EIP_VERBOSE)
+    printf("networkhandler: UDP socket %d\n", newfd);
+
+  /* check if it is sending or receiving */
+  if (pa_nDirection == CONSUMING)
+    { /* bind is only for consuming necessary */
+      if ((bind(newfd, (struct sockaddr *) pa_pstAddr, sizeof(struct sockaddr)))
+          == -1)
+        {
+          printf("error on bind udp\n");
+          return EIP_ERROR;
+        }
+      if (EIP_DEBUG >= EIP_VERBOSE)
+        printf("networkhandler: bind UDP socket %d\n", newfd);
+    }
+
+  /* add new fd to the master list */
+  FD_SET(newfd, &master);
+  if (newfd > fdmax)
+    {
+      fdmax = newfd;
+    }
+  return newfd;
+}
+
+void
+IApp_CloseSocket(int pa_nSockFd)
+{
+  if (EIP_INVALID_SOCKET != pa_nSockFd)
+    {
+      FD_CLR(pa_nSockFd, &master);
+      close(pa_nSockFd);
+    }
+}

+ 7 - 2
src/typedefs.h

@@ -59,15 +59,20 @@ typedef enum
   {
     EIP_OK = 0,
     EIP_OK_SEND = 1,
-    EIP_ERROR = -1,
+    EIP_ERROR = -1
   } EIP_STATUS;
 
-typedef enum /* define C++ -like "bool"*/
+
+#ifndef __cplusplus
+/*! If we don't have C++ define a C++ -like "bool"*/
+typedef enum
   {
     false=0,
     true=1
   }bool;
 
+#endif
+
 /* by default an enum is 32 bits
  __attribute((packed)) allows the compiler to use a shorter data type
  the following forces an enum to a specified minimum length, it also documents the size of the enum