DESERT 3.5.1
Loading...
Searching...
No Matches
uwApplication_TCP_socket.cpp
Go to the documentation of this file.
1//
2// Copyright (c) 2017 Regents of the SIGNET lab, University of Padova.
3// All rights reserved.
4//
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions
7// are met:
8// 1. Redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer.
10// 2. Redistributions in binary form must reproduce the above copyright
11// notice, this list of conditions and the following disclaimer in the
12// documentation and/or other materials provided with the distribution.
13// 3. Neither the name of the University of Padova (SIGNET lab) nor the
14// names of its contributors may be used to endorse or promote products
15// derived from this software without specific prior written permission.
16//
17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
21// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28//
29
40#include <sstream>
41#include <time.h>
44#include <error.h>
45#include <errno.h>
46
47pthread_mutex_t mutex_tcp = PTHREAD_MUTEX_INITIALIZER;
48
49int
51{
52 int sockoptval = 1;
53
54 // Create socket for incoming connections
55 if ((servSockDescr = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
56 if (debug_ >= 0)
57 std::cout << getEpoch() << "::" << NOW
58 << "::UWAPPLICATION::OPEN_CONNECTION_TCP::SOCKET_"
59 "CREATION_FAILED"
60 << endl;
61 if (logging)
62 out_log << left << getEpoch() << "::" << NOW
63 << "::UWAPPLICATION::OPEN_CONNECTION_TCP::SOCKET_CREATION_"
64 "FAILED"
65 << endl;
66 exit(1);
67 }
68
69 if (setsockopt(servSockDescr, SOL_SOCKET, SO_REUSEADDR, &sockoptval, sizeof(int)) == -1) {
70 if(debug_ >=0)
71 std::cout << getEpoch() << "::" << NOW
72 << "::UWAPPLICATION::ERROR::REUSABLE_FAIL"
73 << std::endl;
74 }
75
76 if (debug_ >= 2)
77 std::cout << getEpoch() << "::" << NOW
78 << "::UWAPPLICATION::OPEN_CONNECTION_TCP::SOCKET_CREATED"
79 << endl;
80
81 // Fill the members of sockaddr_in structure
82 memset(&servAddr, 0, sizeof(servAddr));
83 servAddr.sin_family = AF_INET;
84 servAddr.sin_port = htons(servPort);
85 servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
86
87 // Bind to the local address
88 if (::bind(servSockDescr, (struct sockaddr *) &servAddr, sizeof(servAddr)) <
89 0) {
90 if (debug_ >= 0)
91 std::cout << getEpoch() << "::" << NOW
92 << "::UWAPPLICATION::OPEN_CONNECTION_TCP::BINDING_FAILED_"
93 << strerror(errno) << endl;
94 if (logging)
95 out_log << left << getEpoch() << "::" << NOW
96 << "::UWAPPLICATION::OPEN_CONNECTION_TCP::BINDING_FAILED_"
97 << strerror(errno) << endl;
98 exit(1);
99 }
100
101 // Listen for incoming connections
102 if (listen(servSockDescr, 1)) {
103 if (debug_ >= 0)
104 std::cout << getEpoch() << "::" << NOW
105 << "::UWAPPLICATION::OPEN_CONNECTION_TCP::LISTEN_FAILED"
106 << endl;
107 if (logging)
108 out_log << left << getEpoch() << "::" << NOW
109 << "::UWAPPLICATION::OPEN_CONNECTION_TCP::LISTEN_FAILED"
110 << endl;
111 exit(1);
112 }
113 if (debug_ >= 2)
114 std::cout << getEpoch() << "::" << NOW
115 << "::UWAPPLICATION::OPEN_CONNECTION_TCP::SERVER_READY"
116 << endl;
117
118 chkTimerPeriod.resched(getPeriod());
119 pthread_t pth;
120 if (pthread_create(&pth, NULL, read_process_TCP, (void *) this) != 0) {
121 if (debug_ >= 0)
122 std::cout << getEpoch() << "::" << NOW
123 << "::UWAPPLICATION::OPEN_CONNECTION_TCP::CANNOT_CREATE_"
124 "PARRALEL_THREAD"
125 << endl;
126 if (logging)
127 out_log << left << getEpoch() << "::" << NOW
128 << "::UWAPPLICATION::OPEN_CONNECTION_TCP::CANNOT_CREATE_"
129 "PARRALEL_"
130 "THREAD"
131 << endl;
132 exit(1);
133 }
134
135 return servSockDescr;
136} // end openConnectionTCP() method
137
138void *
140{
142 int debug_ = 1;
143 // struct sockaddr_in clnAddr;
144
145 socklen_t clnLen = sizeof(sockaddr_in);
146 // int clnSockDescr;
147
148 clnLen = sizeof(obj->clnAddr);
149
150 while (true) {
151 if ((obj->clnSockDescr = accept(obj->servSockDescr,
152 (struct sockaddr *) &(obj->clnAddr),
153 (socklen_t *) &clnLen)) < 0) {
154 if (debug_ >= 0)
155 std::cout << obj->getEpoch() << "::" << NOW
156 << "::UWAPPLICATION::READ_PROCESS_TCP::CONNECTION_"
157 "NOT_ACCEPTED"
158 << endl;
159 }
160 if (debug_ >= 1)
161 std::cout << obj->getEpoch() << "::" << NOW
162 << "::UWAPPLICATION::READ_PROCESS_TCP::NEW_CLIENT_IP_"
163 << inet_ntoa(obj->clnAddr.sin_addr) << std::endl;
164 if (obj->logging)
165 obj->out_log << left << obj->getEpoch() << "::" << NOW
166 << "::UWAPPLICATION::READ_PROCESS_TCP::NEW_CLIENT_IP_"
167 << inet_ntoa(obj->clnAddr.sin_addr) << std::endl;
168 obj->handleTCPclient(obj->clnSockDescr);
169 }
170
171} // end read_process_TCP() method
172
173void
175{
176 while (true) {
177 int recvMsgSize = 0;
178 char buffer_msg[MAX_LENGTH_PAYLOAD];
179 Packet *p = Packet::alloc();
181 for (int i = 0; i < MAX_LENGTH_PAYLOAD; i++) {
182 buffer_msg[i] = 0;
183 }
184 if ((recvMsgSize = read(clnSock, buffer_msg, MAX_READ_LEN)) < 0) {
185 if (debug_ >= 0)
186 std::cout << getEpoch() << "::" << NOW
187 << "::UWAPPLICATION::READ_PROCESS_TCP::HANDLE_TCP_"
188 "CLIENT::"
189 "CONNECTION_NOT_ACCEPTED"
190 << endl;
191 break;
192 }
193 if (recvMsgSize == 0) { // client disconnected
194 shutdown(clnSock, 2);
195 break;
196 } else {
197 int status = pthread_mutex_lock(&mutex_tcp);
198 if (status != 0) {
199 if (debug_ >= 0)
200 std::cout << getEpoch() << "::" << NOW
201 << "::UWAPPLICATION::PTHREAD_MUTEX_LOCK_FAILED "
202 << endl;
203 }
204 if (debug_ >= 0) {
205 std::cout << getEpoch() << "::" << NOW
206 << "::UWAPPLICATION::READ_PROCESS_TCP::PAYLOAD_"
207 "MESSAGE--> ";
208 for (int i = 0; i < recvMsgSize; i++) {
209 cout << buffer_msg[i];
210 }
211 }
212 if (logging)
213 out_log << left << getEpoch() << "::" << NOW
214 << "::UWAPPLICATION::READ_PROCESS_UDP::NEW_PACKET_"
215 "CREATED"
216 << endl;
217 for (int i = 0; i < recvMsgSize; i++) {
218 hdr_Appl->payload_msg[i] = buffer_msg[i];
219 }
220 hdr_cmn *ch = HDR_CMN(p);
221 ch->size() = recvMsgSize;
222 hdr_Appl->payload_size() = recvMsgSize;
223 queuePckReadTCP.push(p);
225 status = pthread_mutex_unlock(&mutex_tcp);
226 if (status != 0) {
227 if (debug_ >= 0)
228 std::cout << getEpoch() << "::" << NOW
229 << "::UWAPPLICATION::PTHREAD_MUTEX_UNLOCK_FAILED "
230 << endl;
231 }
232 }
233 }
234}
235
236void
238{
239 if (queuePckReadTCP.empty()) {
240 } else {
241 Packet *ptmp = queuePckReadTCP.front();
242 queuePckReadTCP.pop();
243 hdr_cmn *ch = HDR_CMN(ptmp);
244 hdr_uwudp *uwudph = hdr_uwudp::access(ptmp);
245 hdr_uwip *uwiph = hdr_uwip::access(ptmp);
247
248 // Common header fields
249 ch->uid_ = uidcnt++;
250 ch->ptype_ = PT_DATA_APPLICATION;
251 ch->direction_ = hdr_cmn::DOWN;
252 ch->timestamp() = Scheduler::instance().clock();
253
254 // Transport header fields
255 uwudph->dport() = port_num;
256
257 // IP header fields
258 uwiph->daddr() = dst_addr;
259
260 // uwApplication packet header fields
261 uwApph->sn_ = txsn++; // Sequence number to the data packet
262 if (rftt >= 0) {
263 uwApph->rftt_ = (int) (rftt * 10000); // Forward Trip Time
264 uwApph->rftt_valid_ = true;
265 } else {
266 uwApph->rftt_valid_ = false;
267 }
268 uwApph->priority_ = 0; // Priority of the message
269 if (debug_ >= 2)
270 std::cout << getEpoch() << "::" << NOW
271 << "::UWAPPLICATION::INIT_PACKET_TCP::UID_" << ch->uid_
272 << endl;
273 if (debug_ >= 0)
274 std::cout << getEpoch() << "::" << NOW
275 << "::UWAPPLICATION::INIT_PACKET_TCP::DEST_"
276 << (int) uwiph->daddr() << endl;
277 if (debug_ >= 0)
278 std::cout << getEpoch() << "::" << NOW
279 << "::UWAPPLICATION::INIT_PACKET_TCP::SIZE_"
280 << (int) uwApph->payload_size() << endl;
281 if (debug_ >= 0)
282 std::cout << getEpoch() << "::" << NOW
283 << "::UWAPPLICATION::INIT_PACKET_TCP::SN_"
284 << (int) uwApph->sn_ << endl;
285 if (debug_ >= 0)
286 std::cout << getEpoch() << "::" << NOW
287 << "::UWAPPLICATION::INIT_PACKET_TCP::INIT_PACKET_TCP::"
288 "SEND_"
289 "DOWN_PACKET"
290 << endl;
291
292 if (logging)
293 out_log << left << getEpoch() << "::" << NOW
294 << "::UWAPPLICATION::INIT_PACKET_TCP::UID_" << ch->uid_
295 << endl;
296 if (logging)
297 out_log << left << getEpoch() << "::" << NOW
298 << "::UWAPPLICATION::INIT_PACKET_TCP::DEST_"
299 << (int) uwiph->daddr() << endl;
300 if (logging)
301 out_log << left << getEpoch() << "::" << NOW
302 << "::UWAPPLICATION::INIT_PACKET_TCP::SIZE_"
303 << (int) uwApph->payload_size() << endl;
304 if (logging)
305 out_log << left << getEpoch() << "::" << NOW
306 << "::UWAPPLICATION::INIT_PACKET_TCP::SN_"
307 << (int) uwApph->sn_ << endl;
308 if (logging)
309 out_log << left << getEpoch() << "::" << NOW
310 << "::UWAPPLICATION::INIT_PACKET_TCP::INIT_PACKET_TCP::"
311 "SEND_DOWN_"
312 "PACKET"
313 << endl;
314 sendDown(ptmp);
315 }
316}
uwSendTimerAppl chkTimerPeriod
Timer that schedule the period between two successive generation of DATA packets.
int servSockDescr
socket descriptor for server
int rftt
Forward trip time.
int debug_
Used for debug purposes 1 debug activated 0 debug not activated.
virtual void handleTCPclient(int clnSock)
Handle the communication between server and client.
virtual void incrPktsPushQueue()
Increase the number of DATA packets stored in the Server queue.
int uidcnt
Identifier counter that identify uniquely the DATA packet generated.
virtual int openConnectionTCP()
When socket communication is used, this method establish a connection between client and server.
int clnSockDescr
*socket descriptor for client
unsigned long int getEpoch()
Calculate the epoch of the event.
struct sockaddr_in servAddr
Server address.
std::ofstream out_log
Variable that handle the file in which the protocol write the statistics.
static uint MAX_READ_LEN
Maximum size (bytes) of a single read of the socket.
int port_num
Number of the port in which the server provide the service.
struct sockaddr_in clnAddr
Client address.
uint8_t dst_addr
IP destination address.
virtual double getPeriod()
return period generation time
std::queue< Packet * > queuePckReadTCP
Queue that store the DATA packets recevied from the client by the server using a TCP protocol.
virtual void init_Packet_TCP()
Set all the field of DATA packet and take from the specific queue the payload of DATA packet that wil...
int txsn
Transmission sequence number of DATA packet.
Content header of TRIGGER packet.
int rftt_
Forward Trip Time of the packet.
char payload_msg[MAX_LENGTH_PAYLOAD]
Message payload.
uint16_t sn_
Serial number of the packet.
bool rftt_valid_
Flag used to set the validity of the fft field.
uint8_t priority_
Priority flag: 1 means high priority, 0 normal priority.
hdr_uwip describes UWIP packets.
Definition uwip-module.h:70
uint8_t & daddr()
Reference to the daddr_ variable.
static hdr_uwip * access(const Packet *p)
Definition uwip-module.h:86
hdr_uwudp describes UWUDP packets.
static struct hdr_uwudp * access(const Packet *p)
uint8_t & dport()
Reference to the dport_ variable.
void * read_process_TCP(void *arg)
pthread_mutex_t mutex_tcp
Provides the headers of the data packet.
#define MAX_LENGTH_PAYLOAD
#define HDR_DATA_APPLICATION(p)
alias defined to access the TRIGGER HEADER
packet_t PT_DATA_APPLICATION
Trigger packet type for UFetch protocol.
void * read_process_TCP(void *arg)