udp_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
36 #else
37 #include "udp_socket.h"
38 #include "log_wrapper.h"
39 #include "simple_message.h"
40 #endif
41 
42 
43 using namespace industrial::smpl_msg_connection;
44 using namespace industrial::byte_array;
45 using namespace industrial::simple_message;
46 using namespace industrial::shared_types;
47 
48 namespace industrial
49 {
50 namespace udp_socket
51 {
52 
53 UdpSocket::UdpSocket()
54 // Constructor for UDP socket object
55 {
56  memset(&this->udp_read_buffer_, 0, sizeof(this->udp_read_buffer_));
57  udp_read_head_ = this->udp_read_buffer_;
58  udp_read_len_ = 0;
59 }
60 
61 UdpSocket::~UdpSocket()
62 // Destructor for UDP socket object
63 // Closes socket
64 {
65  CLOSE(this->getSockHandle());
66 }
67 
68 int UdpSocket::rawSendBytes(char *buffer, shared_int num_bytes)
69 {
70  int rc = this->SOCKET_FAIL;
71 
72  rc = SEND_TO(this->getSockHandle(), buffer,
73  num_bytes, 0, (sockaddr *)&this->sockaddr_,
74  sizeof(this->sockaddr_));
75 
76  return rc;
77 }
78 
79 int UdpSocket::rawReceiveBytes(char *buffer, shared_int num_bytes)
80 {
81  int rc, len_cpy;
82  SOCKLEN_T addrSize;
83 
84  if(udp_read_len_ == 0) {
85  // there is currently no data in the temporary buffer, do a socket read
86  addrSize = sizeof(this->sockaddr_);
87 
88  rc = RECV_FROM(this->getSockHandle(), &this->udp_read_buffer_[0], this->MAX_BUFFER_SIZE,
89  0, (sockaddr *)&this->sockaddr_, &addrSize);
90  if(rc <= 0)
91  return 0; // either we had an error or read no data, don't update the buffer
92  udp_read_head_ = this->udp_read_buffer_;
93  udp_read_len_ = rc;
94  }
95  if(num_bytes == 0 || num_bytes >= udp_read_len_) // read all data available
96  len_cpy = udp_read_len_;
97  else
98  len_cpy = num_bytes;
99  memcpy(buffer, udp_read_head_, len_cpy);
100  udp_read_head_ += len_cpy; // shift pointer in buffer
101  udp_read_len_ -= len_cpy;
102  return len_cpy;
103 }
104 
105 bool UdpSocket::rawPoll(int timeout, bool & ready, bool & error)
106 {
107  if(udp_read_len_ > 0) {
108  // we still have data in the buffer, we can read without socket calls
109  ready = true;
110  error = false;
111  return true;
112  }
113 
114  timeval time;
115  fd_set read, write, except;
116  int rc = this->SOCKET_FAIL;
117  bool rtn = false;
118  ready = false;
119  error = false;
120 
121  // The select function uses the timeval data structure
122  time.tv_sec = timeout / 1000;
123  time.tv_usec = (timeout % 1000) * 1000;
124 
125  FD_ZERO(&read);
126  FD_ZERO(&write);
127  FD_ZERO(&except);
128 
129  FD_SET(this->getSockHandle(), &read);
130  FD_SET(this->getSockHandle(), &except);
131 
132  rc = SELECT(this->getSockHandle() + 1, &read, &write, &except, &time);
133 
134  if (this->SOCKET_FAIL != rc) {
135  if (0 == rc)
136  rtn = false;
137  else {
138  if (FD_ISSET(this->getSockHandle(), &read)) {
139  ready = true;
140  rtn = true;
141  }
142  else if(FD_ISSET(this->getSockHandle(), &except)) {
143  error = true;
144  rtn = true;
145  }
146  else {
147  LOG_WARN("Select returned, but no flags are set");
148  rtn = false;
149  }
150  }
151  } else {
152  this->logSocketError("Socket select function failed", rc, errno);
153  rtn = false;
154  }
155  return rtn;
156 }
157 
158 } //udp_socket
159 } //industrial
160 
Contains platform specific type definitions that guarantee the size of primitive data types...
Definition: shared_types.h:52
#define LOG_WARN(format,...)
Definition: log_wrapper.h:107


simple_message
Author(s): Shaun Edwards
autogenerated on Sat Sep 21 2019 03:30:09