OpENer - Open Source EtherNet/IP(TM) I/O Target Stack  2.1
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
cipethernetlink.c
Go to the documentation of this file.
1 /*******************************************************************************
2  * Copyright (c) 2009, Rockwell Automation, Inc.
3  * All rights reserved.
4  *
5  ******************************************************************************/
6 #include <string.h>
7 
8 #include "cipethernetlink.h"
9 
10 #include "cipcommon.h"
11 #include "cipmessagerouter.h"
12 #include "ciperror.h"
13 #include "endianconv.h"
14 #include "opener_api.h"
15 #include "trace.h"
16 
17 typedef struct {
21 
22 typedef struct speed_duplex_array_entry {
26 
27 typedef struct speed_duplex_options {
31 
32 typedef struct {
36 
38  CipInstance *RESTRICT const instance,
39  CipMessageRouterRequest *const message_router_request,
40  CipMessageRouterResponse *const message_router_response,
41  struct sockaddr *originator_address,
42  const int encapsulation_session);
43 
51 
52 CipShortString interface_label = { .length = 0, .string = NULL };
54  .forced_interface_speed =
55  0 };
56 
58  100, .
59  interface_duplex_mode
60  = 1 };
62  .capability_bits = 1, .speed_duplex_options = { .speed_duplex_array_count =
63  1,
64  .speed_duplex_array =
65  &speed_duplex_object }
66 };
67 
70  0, /* # class attributes*/
71  7, /* # highest class attribute number*/
72  2, /* # class services*/
73  11, /* # instance attributes*/
74  11, /* # highest instance attribute number*/
75  2, /* # instance services*/
76  1, /* # instances*/
77  "Ethernet Link", 4, /* # class revision*/
78  NULL); /* # function pointer for initialization*/
79 
80  /* set attributes to initial values */
82  g_ethernet_link.interface_flags = 0xF; /* successful speed and duplex neg, full duplex active link, TODO in future it should be checked if link is active */
83 
84  if (ethernet_link_class != NULL) {
85  CipInstance *ethernet_link_instance = GetCipInstance(ethernet_link_class,
86  1);
87  InsertAttribute(ethernet_link_instance, 1, kCipUdint,
88  &g_ethernet_link.interface_speed, kGetableSingleAndAll); /* bind attributes to the instance*/
89  InsertAttribute(ethernet_link_instance, 2, kCipDword,
91  InsertAttribute(ethernet_link_instance, 3, kCip6Usint,
93  InsertAttribute(ethernet_link_instance, 4, kCipUsint,
95  InsertAttribute(ethernet_link_instance, 5, kCipUsint,
97  InsertAttribute(ethernet_link_instance, 6, kCipUdint, &interface_control,
98  kGetableAll);
99  InsertAttribute(ethernet_link_instance, 7, kCipUsint,
101  InsertAttribute(ethernet_link_instance, 8, kCipUsint,
103  InsertAttribute(ethernet_link_instance, 9, kCipUsint,
105  InsertAttribute(ethernet_link_instance, 10, kCipShortString,
106  &interface_label, kGetableAll);
107  InsertAttribute(ethernet_link_instance, 11, kCipAny, &interface_capability,
109 
110  InsertService(ethernet_link_class, kGetAttributeSingle,
111  &GetAttributeSingleEthernetLink, "GetAttributeSingle");
112  InsertService(ethernet_link_class, kGetAttributeAll, &GetAttributeAll,
113  "GetAttributeAll");
114  } else {
115  return kEipStatusError;
116  }
117 
118  return kEipStatusOk;
119 }
120 
122 // Returns default value 0
123  int return_value = 0;
124  for (int i = 0; i < 11; i++) {
125  return_value += EncodeData(kCipUdint, &dummy_attribute_udint, pa_acMsg);
126  }
127  return return_value;
128 }
129 
130 int EncodeMediaCounters(EipUint8 **pa_acMsg) {
131 // Returns default value 0
132  int return_value = 0;
133  for (int i = 0; i < 12; i++) {
134  return_value += EncodeData(kCipUdint, &dummy_attribute_udint, pa_acMsg);
135  }
136  return return_value;
137 }
138 
140 // Returns default value 0
141  int return_value = 0;
142  return_value += EncodeData(kCipWord, &interface_control.control_bits,
143  pa_acMsg);
144  return_value += EncodeData(kCipUint,
145  &interface_control.forced_interface_speed,
146  pa_acMsg);
147  return return_value;
148 }
149 
151  int return_value = 0;
152  return_value += EncodeData(kCipDword, &interface_capability.capability_bits,
153  pa_acMsg);
154  return_value += EncodeData(
155  kCipUsint,
156  &interface_capability.speed_duplex_options.speed_duplex_array_count,
157  pa_acMsg);
158 
159  for (CipUsint i = 0;
160  i < interface_capability.speed_duplex_options.speed_duplex_array_count;
161  i++) {
162  return_value += EncodeData(
163  kCipUint,
164  &(interface_capability.speed_duplex_options.speed_duplex_array[i]
165  .interface_speed),
166  pa_acMsg);
167  return_value += EncodeData(
168  kCipUsint,
169  &(interface_capability.speed_duplex_options.speed_duplex_array[i]
171  pa_acMsg);
172  }
173  return return_value;
174 }
175 
177  CipInstance *RESTRICT const instance,
178  CipMessageRouterRequest *const message_router_request,
179  CipMessageRouterResponse *const message_router_response,
180  struct sockaddr *originator_address,
181  const int encapsulation_session) {
182  /* Mask for filtering get-ability */
183 
184  CipAttributeStruct *attribute = GetCipAttribute(
185  instance, message_router_request->request_path.attribute_number);
186  EipByte *message = message_router_response->data;
187 
188  message_router_response->data_length = 0;
189  message_router_response->reply_service = (0x80
190  | message_router_request->service);
191  message_router_response->general_status = kCipErrorAttributeNotSupported;
192  message_router_response->size_of_additional_status = 0;
193 
194  EipUint16 attribute_number = message_router_request->request_path
196 
197  if ( (NULL != attribute) && (NULL != attribute->data) ) {
198  uint8_t get_bit_mask = 0;
199  if (kGetAttributeAll == message_router_request->service) {
200  get_bit_mask = (instance->cip_class->get_all_bit_mask[CalculateIndex(
201  attribute_number)]);
202  message_router_response->general_status = kCipErrorSuccess;
203  } else {
204  get_bit_mask = (instance->cip_class->get_single_bit_mask[CalculateIndex(
205  attribute_number)
206  ]);
207  }
208  if ( 0 != ( get_bit_mask & ( 1 << (attribute_number % 8) ) ) ) {
209  OPENER_TRACE_INFO("getAttribute %d\n",
210  message_router_request->request_path.attribute_number); /* create a reply message containing the data*/
211 
212  switch (attribute_number) {
213  case 4:
214  message_router_response->data_length = EncodeInterfaceCounters(
215  &message);
216  message_router_response->general_status = kCipErrorSuccess;
217  break;
218  case 5:
219  message_router_response->data_length = EncodeMediaCounters(&message);
220  message_router_response->general_status = kCipErrorSuccess;
221  break;
222  case 6:
223  message_router_response->data_length = EncodeInterfaceControl(
224  &message);
225  message_router_response->general_status = kCipErrorSuccess;
226  break;
227  case 11:
228  message_router_response->data_length = EncodeInterfaceCapability(
229  &message);
230  message_router_response->general_status = kCipErrorSuccess;
231  break;
232 
233  default:
234  GetAttributeSingle(instance, message_router_request,
235  message_router_response,
236  originator_address,
237  encapsulation_session);
238  }
239 
240  }
241  }
242 
243  return kEipStatusOkSend;
244 }
245 
CIP Short String.
Definition: ciptypes.h:130
void InsertAttribute(CipInstance *const instance, const EipUint16 attribute_number, const EipUint8 cip_type, void *const data, const EipByte cip_flags)
Insert an attribute in an instance of a CIP class.
Definition: cipcommon.c:304
Tracing infrastructure for OpENer.
CipUint interface_duplex_mode
EipUint8 physical_address[6]
CIP Message Router Request.
Definition: ciptypes.h:187
Class is a subclass of Instance.
Definition: ciptypes.h:237
Responsible for Endianess conversion.
size_t CalculateIndex(EipUint16 attribute_number)
Calculates Byte-Index of Attribute.
Definition: cipcommon.c:895
CipClass * CreateCipClass(const EipUint32 class_id, const int number_of_class_attributes, const EipUint32 highest_class_attribute_number, const int number_of_class_services, const int number_of_instance_attributes, const EipUint32 highest_instance_attribute_number, const int number_of_instance_services, const int number_of_instances, char *name, const EipUint16 revision, void(*InitializeCipClass)(CipClass *))
Definition: cipcommon.c:189
EipStatus
EIP stack status enum.
Definition: typedefs.h:93
uint8_t EipUint8
Definition: typedefs.h:32
void InsertService(const CipClass *const class, const EipUint8 service_number, const CipServiceFunction service_function, char *const service_name)
Insert a service in an instance of a CIP object.
Definition: cipcommon.c:346
EipStatus GetAttributeAll(CipInstance *instance, CipMessageRouterRequest *message_router_request, CipMessageRouterResponse *message_router_response, struct sockaddr *originator_address, const int encapsulation_session)
Generic implementation of the GetAttributeAll CIP service.
Definition: cipcommon.c:704
struct speed_duplex_array_entry * speed_duplex_array
#define OPENER_TRACE_INFO(...)
Definition: trace.h:89
CipUint interface_speed
EipStatus GetAttributeSingle(CipInstance *RESTRICT const instance, CipMessageRouterRequest *const message_router_request, CipMessageRouterResponse *const message_router_response, struct sockaddr *originator_address, const int encapsulation_session)
Generic implementation of the GetAttributeSingle CIP service.
Definition: cipcommon.c:391
int EncodeData(const EipUint8 cip_type, const void *const cip_data, EipUint8 **cip_message)
Produce the data according to CIP encoding onto the message buffer.
Definition: cipcommon.c:450
uint8_t CipUsint
Definition: typedefs.h:46
CipInstance * GetCipInstance(const CipClass *RESTRICT const cip_class, EipUint32 instance_number)
Get a pointer to an instance.
CipAttributeStruct * GetCipAttribute(const CipInstance *const instance, const EipUint16 attribute_number)
Get a pointer to an instance's attribute.
Definition: cipcommon.c:373
EipUint16 attribute_number
Definition: ciptypes.h:156
uint8_t EipByte
EIP Data type definitions.
Definition: typedefs.h:28
struct speed_duplex_options speed_duplex_options
uint32_t CipUdint
Definition: typedefs.h:48
uint16_t CipUint
Definition: typedefs.h:47
CIP Message Router Response.
Definition: ciptypes.h:199
EipUint8 length
Definition: ciptypes.h:131
uint32_t CipDword
Definition: typedefs.h:45
uint16_t CipWord
Definition: typedefs.h:44
CipUsint speed_duplex_array_count
uint16_t EipUint16
Definition: typedefs.h:33
CipUsint size_of_additional_status
Definition: ciptypes.h:205