OpENer - Open Source EtherNet/IP(TM) I/O Target Stack  2.1
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
endianconv.c
Go to the documentation of this file.
1 /*******************************************************************************
2  * Copyright (c) 2009, Rockwell Automation, Inc.
3  * All rights reserved.
4  *
5  ******************************************************************************/
6 
7 #ifdef WIN32
8 #include <winsock2.h>
9 #else
10 #include <netinet/in.h>
11 #include <sys/socket.h>
12 #endif
13 
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17 
18 #include "endianconv.h"
19 
21 
22 /* THESE ROUTINES MODIFY THE BUFFER POINTER*/
23 
29 EipUint8 GetSintFromMessage(const EipUint8 **const buffer) {
30  const unsigned char *const buffer_address = (unsigned char *) *buffer;
31  EipUint8 data = buffer_address[0];
32  *buffer += 1;
33  return data;
34 }
35 
36 CipByte GetByteFromMessage(const CipOctet **const buffer_address) {
37  const CipOctet *buffer = *buffer_address;
38  CipByte data = buffer[0];
39  *buffer_address += 1;
40  return data;
41 }
42 
43 CipUsint GetUsintFromMessage(const CipOctet **const buffer_address) {
44  const CipOctet *buffer = *buffer_address;
45  CipUsint data = buffer[0];
46  *buffer_address += 1;
47  return data;
48 }
49 
50 /* little-endian-to-host unsigned 16 bit*/
51 
57 EipUint16 GetIntFromMessage(const EipUint8 **const buffer) {
58  const unsigned char *const buffer_address = (unsigned char *) *buffer;
59  EipUint16 data = buffer_address[0] | buffer_address[1] << 8;
60  *buffer += 2;
61  return data;
62 }
63 
64 CipUint GetUintFromMessage(const CipOctet **const buffer_address) {
65  const CipOctet *buffer = *buffer_address;
66  EipUint16 data = buffer[0] | buffer[1] << 8;
67  *buffer_address += 2;
68  return data;
69 }
70 
71 CipWord GetWordFromMessage(const CipOctet **const buffer_address) {
72  const CipOctet *buffer = *buffer_address;
73  EipUint16 data = buffer[0] | buffer[1] << 8;
74  *buffer_address += 2;
75  return data;
76 }
77 
83 EipUint32 GetDintFromMessage(const EipUint8 **const buffer) {
84  const unsigned char *p = (unsigned char *) *buffer;
85  EipUint32 data = p[0] | p[1] << 8 | p[2] << 16 | p[3] << 24;
86  *buffer += 4;
87  return data;
88 }
89 
90 CipUdint GetUdintFromMessage(const CipOctet **const buffer_address) {
91  const CipOctet *buffer = *buffer_address;
92  CipUdint data = buffer[0] | buffer[1] << 8 | buffer[2] << 16 | buffer[3] <<
93  24;
94  *buffer_address += 4;
95  return data;
96 }
97 
103 int AddSintToMessage(const EipUint8 data,
104  EipUint8 **const buffer) {
105  unsigned char *p = (unsigned char *) *buffer;
106 
107  p[0] = (unsigned char) data;
108  *buffer += 1;
109  return 1;
110 }
111 
117 int AddIntToMessage(const EipUint16 data,
118  EipUint8 **const buffer) {
119  unsigned char *p = (unsigned char *) *buffer;
120 
121  p[0] = (unsigned char) data;
122  p[1] = (unsigned char) (data >> 8);
123  *buffer += 2;
124  return 2;
125 }
126 
133  EipUint8 **const buffer) {
134  unsigned char *p = (unsigned char *) *buffer;
135 
136  p[0] = (unsigned char) data;
137  p[1] = (unsigned char) (data >> 8);
138  p[2] = (unsigned char) (data >> 16);
139  p[3] = (unsigned char) (data >> 24);
140  *buffer += 4;
141 
142  return 4;
143 }
144 
145 #ifdef OPENER_SUPPORT_64BIT_DATATYPES
146 
152 EipUint64 GetLintFromMessage(const EipUint8 **const buffer) {
153  const EipUint8 *buffer_address = *buffer;
154  EipUint64 data = ( ( ( (EipUint64) buffer_address[0] ) << 56 )
155  & 0xFF00000000000000LL )
156  + ( ( ( (EipUint64) buffer_address[1] ) << 48 ) &
157  0x00FF000000000000LL )
158  + ( ( ( (EipUint64) buffer_address[2] ) << 40 ) &
159  0x0000FF0000000000LL )
160  + ( ( ( (EipUint64) buffer_address[3] ) << 32 ) &
161  0x000000FF00000000LL )
162  + ( ( ( (EipUint64) buffer_address[4] ) << 24 ) &
163  0x00000000FF000000 )
164  + ( ( ( (EipUint64) buffer_address[5] ) << 16 ) &
165  0x0000000000FF0000 )
166  + ( ( ( (EipUint64) buffer_address[6] ) << 8 ) &
167  0x000000000000FF00 )
168  + ( ( (EipUint64) buffer_address[7] ) & 0x00000000000000FF );
169  *buffer += 8;
170  return data;
171 }
172 
178 int AddLintToMessage(const EipUint64 data,
179  EipUint8 **const buffer) {
180  EipUint8 *buffer_address = *buffer;
181  buffer_address[0] = (EipUint8) (data >> 56) & 0xFF;
182  buffer_address[1] = (EipUint8) (data >> 48) & 0xFF;
183  buffer_address[2] = (EipUint8) (data >> 40) & 0xFF;
184  buffer_address[3] = (EipUint8) (data >> 32) & 0xFF;
185  buffer_address[4] = (EipUint8) (data >> 24) & 0xFF;
186  buffer_address[5] = (EipUint8) (data >> 16) & 0xFF;
187  buffer_address[6] = (EipUint8) (data >> 8) & 0xFF;
188  buffer_address[7] = (EipUint8) (data) & 0xFF;
189  (*buffer) += 8;
190 
191  return 8;
192 }
193 
194 #endif
195 
196 
198  EipUint32 address,
199  EipByte **communication_buffer) {
200  int size = 0;
202  size += AddIntToMessage(htons(AF_INET), communication_buffer);
203  size += AddIntToMessage(port, communication_buffer);
204  size += AddDintToMessage(address, communication_buffer);
205 
206  } else {
208  (*communication_buffer)[0] = (unsigned char) (AF_INET >> 8);
209  (*communication_buffer)[1] = (unsigned char) AF_INET;
210  *communication_buffer += 2;
211  size += 2;
212 
213  (*communication_buffer)[0] = (unsigned char) (port >> 8);
214  (*communication_buffer)[1] = (unsigned char) port;
215  *communication_buffer += 2;
216  size += 2;
217 
218  (*communication_buffer)[3] = (unsigned char) address;
219  (*communication_buffer)[2] = (unsigned char) (address >> 8);
220  (*communication_buffer)[1] = (unsigned char) (address >> 16);
221  (*communication_buffer)[0] = (unsigned char) (address >> 24);
222  *communication_buffer += 4;
223  size += 4;
224  } else {
225  fprintf(stderr,
226  "No endianess detected! Probably the DetermineEndianess function was not executed!");
227  exit (EXIT_FAILURE);
228  }
229  }
230  return size;
231 }
232 
240  int i = 1;
241  char *p = (char *) &i;
242  if (p[0] == 1) {
244  } else {
246  }
247 }
248 
256 }
257 
258 int MoveMessageNOctets(const int amount_of_bytes_moved,
259  const CipOctet **message_runner) {
260  (*message_runner) += amount_of_bytes_moved;
261  return amount_of_bytes_moved;
262 }
263 
265  unsigned int amount_of_bytes_written,
266  CipOctet **message) {
267  memset(*message, value, amount_of_bytes_written);
268  return amount_of_bytes_written;
269 }
270 
272  unsigned int amount_of_filled_bytes,
273  CipOctet **message) {
274  FillNextNMessageOctetsWith(value, amount_of_filled_bytes, message);
275  MoveMessageNOctets(amount_of_filled_bytes, (const CipOctet **)message);
276  return amount_of_filled_bytes;
277 }
278 
CipUint GetUintFromMessage(const CipOctet **const buffer_address)
Definition: endianconv.c:64
int FillNextNMessageOctetsWithValueAndMoveToNextPosition(CipOctet value, unsigned int amount_of_filled_bytes, CipOctet **message)
Definition: endianconv.c:271
EipUint32 GetDintFromMessage(const EipUint8 **const buffer)
Reads EIP_UINT32 from *buffer and converts little endian to host.
Definition: endianconv.c:83
Responsible for Endianess conversion.
EipUint8 GetSintFromMessage(const EipUint8 **const buffer)
Reads EIP_UINT8 from *buffer and converts little endian to host.
Definition: endianconv.c:29
int GetEndianess()
Returns global variable g_nOpENerPlatformEndianess, whereas 0 equals little endian and 1 equals big e...
Definition: endianconv.c:254
uint8_t CipOctet
Data types as defined in the CIP Specification Vol 1 Appendix C.
Definition: typedefs.h:41
int AddIntToMessage(const EipUint16 data, EipUint8 **const buffer)
converts UINT16 data from host to little endian an writes it to buffer.
Definition: endianconv.c:117
uint8_t EipUint8
Definition: typedefs.h:32
uint32_t EipUint32
Definition: typedefs.h:34
int AddDintToMessage(const EipUint32 data, EipUint8 **const buffer)
Converts UINT32 data from host to little endian and writes it to buffer.
Definition: endianconv.c:132
OpenerEndianess
Definition: endianconv.h:15
uint8_t CipByte
Definition: typedefs.h:43
int AddSintToMessage(const EipUint8 data, EipUint8 **const buffer)
converts UINT8 data from host to little endian an writes it to buffer.
Definition: endianconv.c:103
int MoveMessageNOctets(const int amount_of_bytes_moved, const CipOctet **message_runner)
Definition: endianconv.c:258
int FillNextNMessageOctetsWith(CipOctet value, unsigned int amount_of_bytes_written, CipOctet **message)
Definition: endianconv.c:264
uint8_t CipUsint
Definition: typedefs.h:46
uint8_t EipByte
EIP Data type definitions.
Definition: typedefs.h:28
CipUdint GetUdintFromMessage(const CipOctet **const buffer_address)
Definition: endianconv.c:90
CipWord GetWordFromMessage(const CipOctet **const buffer_address)
Definition: endianconv.c:71
CipByte GetByteFromMessage(const CipOctet **const buffer_address)
Definition: endianconv.c:36
uint32_t CipUdint
Definition: typedefs.h:48
uint16_t CipUint
Definition: typedefs.h:47
EipUint16 GetIntFromMessage(const EipUint8 **const buffer)
Reads EIP_UINT16 from *buffer and converts little endian to host.
Definition: endianconv.c:57
OpenerEndianess g_opener_platform_endianess
Definition: endianconv.c:20
int EncapsulateIpAddress(EipUint16 port, EipUint32 address, EipByte **communication_buffer)
Encapsulate the sockaddr information as necessary for the Common Packet Format data items...
Definition: endianconv.c:197
void DetermineEndianess()
Detects Endianess of the platform and sets global g_nOpENerPlatformEndianess variable accordingly...
Definition: endianconv.c:239
uint16_t CipWord
Definition: typedefs.h:44
uint16_t EipUint16
Definition: typedefs.h:33
CipUsint GetUsintFromMessage(const CipOctet **const buffer_address)
Definition: endianconv.c:43