simple_socket.cpp
Go to the documentation of this file.
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2011, Yaskawa America, Inc.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  *
10  * * Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  * * Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in the
14  * documentation and/or other materials provided with the distribution.
15  * * Neither the name of the Yaskawa America, Inc., nor the names
16  * of its contributors may be used to endorse or promote products derived
17  * from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #ifndef FLATHEADERS
35 #else
36 #include "simple_socket.h"
37 #include "log_wrapper.h"
38 #endif
39 
40 using namespace industrial::byte_array;
41 using namespace industrial::shared_types;
42 
43 namespace industrial
44 {
45  namespace simple_socket
46  {
47 
48  bool SimpleSocket::sendBytes(ByteArray & buffer)
49  {
50  int rc = this->SOCKET_FAIL;
51  bool rtn = false;
52 
53  if (this->isConnected())
54  {
55  // Nothing restricts the ByteArray from being larger than the what the socket
56  // can handle.
57  if (this->MAX_BUFFER_SIZE > (int)buffer.getBufferSize())
58  {
59 
60  // copy to local array, since ByteArray no longer supports
61  // direct pointer-access to data values
62  std::vector<char> localBuffer;
63  buffer.copyTo(localBuffer);
64  rc = rawSendBytes(&localBuffer[0], localBuffer.size());
65  if (this->SOCKET_FAIL != rc)
66  {
67  rtn = true;
68  }
69  else
70  {
71  rtn = false;
72  logSocketError("Socket sendBytes failed", rc, errno);
73  }
74 
75  }
76  else
77  {
78  LOG_ERROR("Buffer size: %u, is greater than max socket size: %u", buffer.getBufferSize(), this->MAX_BUFFER_SIZE);
79  rtn = false;
80  }
81 
82  }
83  else
84  {
85  rtn = false;
86  LOG_WARN("Not connected, bytes not sent");
87  }
88 
89  if (!rtn)
90  {
91  this->setConnected(false);
92  }
93 
94  return rtn;
95 
96  }
97 
98  bool SimpleSocket::receiveBytes(ByteArray & buffer, shared_int num_bytes, shared_int timeout_ms)
99  {
100  int rc = this->SOCKET_FAIL;
101  bool rtn = false;
102  shared_int remainBytes = num_bytes;
103  shared_int remainTimeMs = timeout_ms;
104  bool ready, error;
105 
106  // Reset the buffer (this is not required since the buffer length should
107  // ensure that we don't read any of the garbage that may be left over from
108  // a previous read), but it is good practice.
109 
110  memset(&this->buffer_, 0, sizeof(this->buffer_));
111 
112  // Doing a sanity check to determine if the byte array buffer is smaller than
113  // what can be received by the socket.
114  if (this->MAX_BUFFER_SIZE > buffer.getMaxBufferSize())
115  {
116  LOG_WARN("Socket buffer max size: %u, is larger than byte array buffer: %u",
117  this->MAX_BUFFER_SIZE, buffer.getMaxBufferSize());
118  }
119  if (this->isConnected())
120  {
121  buffer.init();
122  while (remainBytes > 0 && (timeout_ms < 0 || remainTimeMs > 0))
123  {
124  // Polling the socket results in an "interruptable" socket read. This
125  // allows Control-C to break out of a socket read. Without polling,
126  // a sig-term is required to kill a program in a socket read function.
127  if (this->rawPoll(this->SOCKET_POLL_TO, ready, error))
128  {
129  if(ready)
130  {
131  rc = rawReceiveBytes(this->buffer_, remainBytes);
132  if (this->SOCKET_FAIL == rc)
133  {
134  this->logSocketError("Socket received failed", rc, errno);
135  remainBytes = 0;
136  rtn = false;
137  break;
138  }
139  else if (0 == rc)
140  {
141  LOG_WARN("Recieved zero bytes: %u", rc);
142  remainBytes = 0;
143  rtn = false;
144  break;
145  }
146  else
147  {
148  remainBytes = remainBytes - rc;
149  remainTimeMs = timeout_ms; // Reset the timeout on successful read
150  LOG_COMM("Byte array receive, bytes read: %u, bytes reqd: %u, bytes left: %u",
151  rc, num_bytes, remainBytes);
152  buffer.load(&this->buffer_, rc);
153  if (remainBytes <= 0) {
154  rtn = true;
155  }
156  }
157  }
158  else if(error)
159  {
160  LOG_ERROR("Socket poll returned an error");
161  rtn = false;
162  break;
163  }
164  else
165  {
166  LOG_ERROR("Uknown error from socket poll");
167  rtn = false;
168  break;
169  }
170  }
171  else
172  {
173  remainTimeMs = remainTimeMs - this->SOCKET_POLL_TO;
174  LOG_COMM("Socket poll timeout, trying again");
175  }
176  }
177  }
178  else
179  {
180  LOG_WARN("Not connected, bytes not received");
181  rtn = false;
182  }
183 
184  // Close the socket on all failures except timeouts
185  if (!rtn && (timeout_ms < 0 || remainTimeMs > 0))
186  {
187  this->setConnected(false);
188  }
189  return rtn;
190  }
191 
192  } //simple_socket
193 } //industrial
LOG_WARN
#define LOG_WARN(format,...)
Definition: log_wrapper.h:133
industrial::shared_types
Contains platform specific type definitions that guarantee the size of primitive data types.
Definition: shared_types.h:52
industrial::byte_array::ByteArray::copyTo
void copyTo(std::vector< char > &out)
Copy to std::vector, for raw-ptr access.
Definition: byte_array.cpp:98
industrial
Definition: byte_array.h:45
industrial::byte_array::ByteArray::getMaxBufferSize
unsigned int getMaxBufferSize()
gets current buffer size
Definition: byte_array.cpp:392
simple_socket.h
LOG_ERROR
#define LOG_ERROR(format,...)
Definition: log_wrapper.h:134
industrial::byte_array::ByteArray
The byte array wraps a dynamic array of bytes (i.e. char).
Definition: byte_array.h:80
LOG_COMM
#define LOG_COMM(format,...)
Definition: log_wrapper.h:130
industrial::byte_array::ByteArray::init
void init()
Initializes or Reinitializes an empty buffer.
Definition: byte_array.cpp:62
log_wrapper.h
industrial::shared_types::shared_int
int shared_int
Definition: shared_types.h:62
industrial::byte_array
Definition: byte_array.h:56
industrial::byte_array::ByteArray::load
bool load(industrial::shared_types::shared_bool value)
loads a boolean into the byte array
Definition: byte_array.cpp:142
industrial::byte_array::ByteArray::getBufferSize
unsigned int getBufferSize()
gets current buffer size
Definition: byte_array.cpp:387


simple_message
Author(s): Shaun Edwards
autogenerated on Wed Mar 2 2022 00:24:53