-
Notifications
You must be signed in to change notification settings - Fork 0
/
TargetServer.cpp
183 lines (158 loc) · 4.91 KB
/
TargetServer.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
#include "TargetServer.h"
#include <errnoLib.h>
#include <hostLib.h>
#include <inetLib.h>
#include <sockLib.h>
#include "Task.h"
#include "Timer.h"
#include "WPIErrors.h"
#include <vxWorks.h>
#include <taskLibCommon.h>
#include <sstream>
#include <algorithm>
#include <iostream>
#include <string>
#include "Synchronized.h"
using std::cout;
using std::endl;
using std::istringstream;
using std::string;
static const int BUFLEN = 1024;
static const int SERVER_PORT_NUM = 1130;
#define ACK "ACK"
TargetServer::TargetServer()
: m_serverTask("RATargetServer", (FUNCPTR)s_ServerTask)
, m_newTargetSem (NULL)
, m_stopServer (false)
, m_latest_packet("")
{
StartServerTask();
}
TargetServer::~TargetServer()
{
Stop();
ClearError();
}
int TargetServer::StartServerTask()
{
cout << "Starting target server..." << endl;
if (StatusIsFatal())
{
return -1;
}
int id = 0;
m_stopServer = false;
// Check for prior copy of running task
int oldId = taskNameToId((char*)m_serverTask.GetName());
if(oldId != ERROR)
{
// TODO: Report error. You are in a bad state.
taskDelete(oldId);
}
// spawn target server task
// this is done to ensure that the task is spawned with the
// floating point context save parameter.
bool started = m_serverTask.Start((int)this);
id = m_serverTask.GetID();
if (!started)
{
wpi_setWPIError(TaskError);
return id;
}
taskDelay(1);
cout << "Done: id " << id << endl;
return id;
}
void TargetServer::Start()
{
StartServerTask();
}
void TargetServer::Stop()
{
m_stopServer = true;
}
int TargetServer::s_ServerTask(TargetServer *thisPtr)
{
return thisPtr->ServerTask();
}
/**
* @brief Most of the work done by the server. Get UDP packets containing
* target string and save the latest one.
*/
int TargetServer::ServerTask()
{
struct sockaddr_in serverAddr; /* server's socket address */
struct sockaddr_in clientAddr; /* client's socket address */
char clientRequest[128]; /* request/Message from client */
int sockAddrSize; /* size of socket address structure */
int sFd; /* socket file descriptor */
// char inetAddr[INET_ADDR_LEN];
/* buffer for client's inet addr */
/* set up the local address */
sockAddrSize = sizeof (struct sockaddr_in);
bzero ((char *) &serverAddr, sockAddrSize);
serverAddr.sin_len = (u_char) sockAddrSize;
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons (SERVER_PORT_NUM);
serverAddr.sin_addr.s_addr = htonl (INADDR_ANY);
/* create a UDP-based socket */
printf("Socket call...");
if ((sFd = socket (AF_INET, SOCK_DGRAM, 0)) == ERROR)
{
perror ("socket");
return (ERROR);
}
printf("Success!\n");
/* bind socket to local address */
printf("Binding...");
if (bind (sFd, (struct sockaddr *) &serverAddr, sockAddrSize) == ERROR)
{
perror ("bind");
close (sFd);
return (ERROR);
}
int smallRcvBufferSize = 256; // two d-grams
// hopefully this works
setsockopt(sFd, SOL_SOCKET, SO_RCVBUF, reinterpret_cast<char*>(& smallRcvBufferSize), sizeof(smallRcvBufferSize));
printf("Done!\n");
/* read data from a socket and satisfy requests */
/* read data from a socket and satisfy requests */
FOREVER
{
for (unsigned int i = 0; i < sizeof(clientRequest); ++i) {
clientRequest[i] = 0;
}
//printf("Waiting for a packet...\n");
if (recvfrom (sFd, (char *) &clientRequest, sizeof (clientRequest), 0,
(struct sockaddr *) &clientAddr, &sockAddrSize) == ERROR)
{
perror ("recvfrom");
close (sFd);
return (ERROR);
}
//cout << clientRequest << endl;
//cout << "I recieved a message from the dashboard! '" << clientRequest << "'" << endl;
std::string temp(clientRequest);
// Leave me alone for a while while I copy this here string.
/*if (semTake(m_newTargetSem, 200) != OK) {
continue; // Try again later.
}*/
m_latest_packet = temp;
taskDelay(100);
//semGive(m_newTargetSem);
// Done.
}
}
std::string TargetServer::GetLatestPacket() {
std::string temp;
// Using the target semaphore to regulate access
// to the m_latest_packet string. Shared memory, man.
/*if (semTake(m_newTargetSem, 200) != OK) {
// still waiting for server.
cout << "WARNING: semTake did ont finish, something's up with the TargetServer" << endl;
return "";
}*/
temp = m_latest_packet;
//semGive(m_newTargetSem);
return temp;
}