OpENer - Open Source EtherNet/IP(TM) I/O Target Stack  2.1
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
main.c
Go to the documentation of this file.
1 /*******************************************************************************
2  * Copyright (c) 2009, Rockwell Automation, Inc.
3  * All rights reserved.
4  *
5  ******************************************************************************/
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <signal.h>
9 #include <sys/capability.h>
10 
11 #ifdef OPENER_RT
12 #include <pthread.h>
13 #include <sys/mman.h>
14 #include <sched.h>
15 #include <limits.h>
16 #endif
17 
18 #include "generic_networkhandler.h"
19 #include "opener_api.h"
20 #include "cipcommon.h"
21 #include "trace.h"
22 #include "networkconfig.h"
23 #include "doublylinkedlist.h"
24 #include "cipconnectionobject.h"
25 
26 /******************************************************************************/
31 void LeaveStack(int signal);
32 
33 /******************************************************************************/
38 void *executeEventLoop(
39  );
40 
41 /*****************************************************************************/
44 int g_end_stack = 0;
45 
46 /******************************************************************************/
47 int main(int argc,
48  char *arg[]) {
49 
50  cap_t capabilities;
51  cap_value_t capabilies_list[1];
52 
53  capabilities = cap_get_proc();
54  if (NULL == capabilities) {
55  printf("Could not get capabilities\n");
56  exit(0);
57  }
58 
59  capabilies_list[0] = CAP_NET_RAW;
60  if (-1
61  == cap_set_flag(capabilities, CAP_EFFECTIVE, 1, capabilies_list,
62  CAP_SET) ) {
63  cap_free(capabilities);
64  printf("Could not set CAP_NET_RAW capability\n");
65  exit(0);
66  }
67 
68  if (-1 == cap_set_proc(capabilities) ) {
69  cap_free(capabilities);
70  printf("Could not push CAP_NET_RAW capability to process\n");
71  exit(0);
72  }
73 
74  if (-1 == cap_free(capabilities) ) {
75  printf("Could not free capabilites value\n");
76  exit(0);
77  }
78 
79  if (argc != 2) {
80  printf("Wrong number of command line parameters!\n");
81  printf("The correct command line parameters are:\n");
82  printf("./OpENer interfacename\n");
83  printf(" e.g. ./OpENer eth1\n");
84  exit(0);
85  } else {
89  /* fetch Internet address info from the platform */
91  printf("Network interface %s not found.\n", arg[1]);
92  exit(0);
93  }
96 
97  ConfigureMacAddress(arg[1]);
98  }
99 
100  /* for a real device the serial number should be unique per device */
101  SetDeviceSerialNumber(123456789);
102 
103  /* unique_connection_id should be sufficiently random or incremented and stored
104  * in non-volatile memory each time the device boots.
105  */
106  EipUint16 unique_connection_id = rand();
107 
108  /* Setup the CIP Layer */
109  CipStackInit(unique_connection_id);
110 
111  /* Setup Network Handles */
113  g_end_stack = 0;
114 #ifndef WIN32
115  /* register for closing signals so that we can trigger the stack to end */
116  signal(SIGHUP, LeaveStack);
117 #endif
118 #ifdef OPENER_RT
119  /* Memory lock all*/
120  if (mlockall(MCL_CURRENT | MCL_FUTURE) == -1) {
121  OPENER_TRACE_ERR("mlockall failed: %m\n");
122  exit(-2);
123  }
124 
125  struct sched_param param;
126  pthread_attr_t attr;
127  pthread_t thread;
128  CipUint ret = pthread_attr_init(&attr);
129  if (ret) {
130  OPENER_TRACE_ERR("init pthread attributes failed\n");
131  exit(-2);
132  }
133 
134  /* Set stack size */
135  ret = pthread_attr_setstacksize(&attr, PTHREAD_STACK_MIN);
136  if (ret) {
137  OPENER_TRACE_ERR("setstacksize failed\n");
138  exit(-2);
139  }
140 
141  /* Set policy and priority of the thread */
142  ret = pthread_attr_setschedpolicy(&attr, SCHED_RR);
143  if (ret) {
144  OPENER_TRACE_ERR("setschedpolicy failed\n");
145  exit(-2);
146  }
147  param.sched_priority = 80;
148  ret = pthread_attr_setschedparam(&attr, &param);
149  if (ret) {
150  OPENER_TRACE_ERR("pthread setschedparam failed\n");
151  exit(-2);
152  }
153  /* scheduling parameters */
154  ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
155  if (ret) {
156  OPENER_TRACE_ERR("setinheritsched failed\n");
157  exit(-2);
158  }
159 
160  /* Create a thread with the specified attributes */
161  ret = pthread_create(&thread, &attr, executeEventLoop, NULL);
162  if (ret) {
163  OPENER_TRACE_ERR("create pthread failed\n");
164  exit(-2);
165  }
166 
167  /* Join the thread */
168  ret = pthread_join(thread, NULL);
169  if (ret) {
170  OPENER_TRACE_ERR("join pthread failed: %m\n");
171  }
172  /* Unlock memory */
173  munlockall();
174 #else
176 #endif
177  /* clean up network state */
179  }
180  /* close remaining sessions and connections, cleanup used data */
182 
183  return -1;
184 }
185 
186 void LeaveStack(int signal) {
187  (void) signal; /* kill unused parameter warning */
188  OPENER_TRACE_STATE("got signal HUP\n");
189  g_end_stack = 1;
190 }
191 
193  /* The event loop. Put other processing you need done continually in here */
194  while (1 != g_end_stack) {
196  OPENER_TRACE_ERR("Error in NetworkHandler loop! Exiting OpENer!\n");
197  break;
198  }
199  }
200 }
void CipConnectionObjectListArrayFree(DoublyLinkedListNode **node)
EipStatus NetworkHandlerProcessOnce(void)
Tracing infrastructure for OpENer.
int main(int argc, char *arg[])
Definition: main.c:32
EipStatus NetworkHandlerFinish(void)
void SetDeviceSerialNumber(const EipUint32 serial_number)
Set the serial number of the device's identity object.
Definition: cipidentity.c:54
void * executeEventLoop()
Signal handler function for ending stack execution.
Definition: main.c:192
#define OPENER_TRACE_ERR(...)
Definition: trace.h:86
void ConfigureMacAddress(const char *network_interface)
Configure the MAC address of the device.
Definition: networkconfig.c:31
void CipStackInit(const EipUint16 unique_connection_id)
Initialize and setup the CIP-stack.
Definition: cipcommon.c:36
#define OPENER_TRACE_STATE(...)
Definition: trace.h:88
DoublyLinkedList connection_list
EipStatus ConfigureNetworkInterface(const char *const network_interface)
Configure the data of the network interface of the device.
Definition: networkconfig.c:27
int g_end_stack
Flag indicating if the stack should end its execution.
Definition: main.c:29
void DoublyLinkedListInitialize(DoublyLinkedList *list, NodeMemoryAllocator allocator, NodeMemoryDeallocator deallocator)
void ShutdownCipStack(void)
Shutdown of the CIP stack.
Definition: cipcommon.c:61
void ConfigureDomainName(void)
Configure the domain name of the device.
Definition: networkconfig.c:87
uint16_t CipUint
Definition: typedefs.h:47
EipStatus NetworkHandlerInitialize(void)
Initializes the network handler, shall be implemented by a port-specific networkhandler.
DoublyLinkedListNode * CipConnectionObjectListArrayAllocator()
uint16_t EipUint16
Definition: typedefs.h:33
void LeaveStack(int pa_nSig)
Signal handler function for ending stack execution.
Definition: main.c:89
void ConfigureHostName(void)
Configure the host name of the device.