udp_client.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 #ifndef FLATHEADERS
34 #else
35 #include "udp_client.h"
36 #include "log_wrapper.h"
37 #endif
38 
39 
40 using namespace industrial::byte_array;
41 using namespace industrial::shared_types;
42 
43 namespace industrial
44 {
45 namespace udp_client
46 {
47 
48 UdpClient::UdpClient()
49 {
50 }
51 
52 UdpClient::~UdpClient()
53 {
54 }
55 
56 bool UdpClient::init(char *buff, int port_num)
57 {
58 
59  int rc;
60  bool rtn;
61  addrinfo *result;
62  addrinfo hints = {};
63 
64  /* Create a socket using:
65  * AF_INET - IPv4 internet protocol
66  * SOCK_DGRAM - UDP type
67  * protocol (0) - System chooses
68  */
69  rc = SOCKET(AF_INET, SOCK_DGRAM, 0);
70  if (this->SOCKET_FAIL != rc)
71  {
72  this->setSockHandle(rc);
73 
74  // Initialize address data structure
75  memset(&this->sockaddr_, 0, sizeof(this->sockaddr_));
76  this->sockaddr_.sin_family = AF_INET;
77 
78  // Check for 'buff' as hostname, and use that, otherwise assume IP address
79  hints.ai_family = AF_INET; // Allow IPv4
80  hints.ai_socktype = SOCK_DGRAM; // UDP socket
81  hints.ai_flags = 0; // No flags
82  hints.ai_protocol = 0; // Any protocol
83  hints.ai_canonname = NULL;
84  hints.ai_addr = NULL;
85  hints.ai_next = NULL;
86  if (0 == GETADDRINFO(buff, NULL, &hints, &result))
87  {
88  this->sockaddr_ = *((sockaddr_in *)result->ai_addr);
89  }
90  else
91  {
92  this->sockaddr_.sin_addr.s_addr = INET_ADDR(buff);
93  }
94  this->sockaddr_.sin_port = HTONS(port_num);
95 
96  rtn = true;
97 
98  }
99  else
100  {
101  LOG_ERROR("Failed to create socket, rc: %d", rc);
102  rtn = false;
103  }
104  return rtn;
105 }
106 
107 
108 bool UdpClient::makeConnect()
109 {
110  ByteArray send;
111  char sendHS = this->CONNECT_HANDSHAKE;
112  char recvHS = 0;
113  bool rtn = false;
114  const int timeout = 1000; // Time (ms) between handshake sends
115  int bytesRcvd = 0;
116 
117  if (!this->isConnected())
118  {
119  this->setConnected(false);
120  send.load((void*)&sendHS, sizeof(sendHS));
121 
122  // copy to local array, since ByteArray no longer supports
123  // direct pointer-access to data values
124  const int sendLen = send.getBufferSize();
125  std::vector<char> localBuffer(sendLen);
126  send.unload(localBuffer.data(), sendLen);
127 
128  do
129  {
130  ByteArray recv;
131  recvHS = 0;
132  LOG_DEBUG("UDP client sending handshake");
133  this->rawSendBytes(localBuffer.data(), sendLen);
134  if (this->isReadyReceive(timeout))
135  {
136  bytesRcvd = this->rawReceiveBytes(this->buffer_, 0);
137  LOG_DEBUG("UDP client received possible handshake");
138  recv.init(&this->buffer_[0], bytesRcvd);
139  recv.unload((void*)&recvHS, sizeof(recvHS));
140  }
141  }
142  while(recvHS != sendHS);
143  LOG_INFO("UDP client connected");
144  rtn = true;
145  this->setConnected(true);
146 
147  }
148  else
149  {
150  rtn = true;
151  LOG_WARN("Tried to connect when socket already in connected state");
152  }
153 
154  return rtn;
155 }
156 } //udp_client
157 } //industrial
158 
LOG_INFO
#define LOG_INFO(format,...)
Definition: log_wrapper.h:132
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
Definition: byte_array.h:45
industrial::byte_array::ByteArray::unload
bool unload(industrial::shared_types::shared_bool &value)
unloads a boolean value from the byte array
Definition: byte_array.cpp:233
LOG_ERROR
#define LOG_ERROR(format,...)
Definition: log_wrapper.h:134
LOG_DEBUG
#define LOG_DEBUG(format,...)
Definition: log_wrapper.h:131
industrial::byte_array::ByteArray
The byte array wraps a dynamic array of bytes (i.e. char).
Definition: byte_array.h:80
industrial::byte_array::ByteArray::init
void init()
Initializes or Reinitializes an empty buffer.
Definition: byte_array.cpp:62
log_wrapper.h
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
udp_client.h
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