root/vtcross/trunk/src/lib/socketcomm/socketcomm.cpp @ 216

Revision 216, 7.4 KB (checked in by bhilburn, 15 years ago)

Applying style/semantic fixes to socketcomm.cpp. Removed
unimplemented/unused function decleration from socketcomm.h.

Line 
1/* Virginia Tech Cognitive Radio Open Source Systems
2 * Virginia Tech, 2009
3 *
4 * TODO LICENSE INFORMATION GOES HERE
5 */
6
7/* TODO DESCRIPTION OF FILE.
8 */
9
10
11#include <arpa/inet.h>
12#include <cstdlib>
13#include <cstring>
14#include <iostream>
15#include <fcntl.h>
16#include <sys/ioctl.h>
17#include <netdb.h>
18#include <netinet/in.h>
19#include <stdint.h>
20#include <string>
21#include <sys/types.h>
22#include <sys/socket.h>
23
24#include "vtcross/common.h"
25#include "vtcross/containers.h"
26#include "vtcross/debug.h"
27#include "vtcross/error.h"
28#include "vtcross/socketcomm.h"
29
30
31// TODO can someone write a description of how this function is operating? I'm
32// not sure I understand why it is making two separate blocking calls to recv
33//
34// TODO also, it appears that this function can, at maximum, receive 256 bytes
35// without causing a buffer overflow. can someone confirm/deny?
36void
37ReadMessage(int32_t socketFD, char* msgBuffer)
38{
39
40    // Peek at the buffer to get real message length.
41    // Messages are termination with a "\0" to denote EOM.
42    ssize_t msgLength = recv(socketFD, msgBuffer, 256, MSG_PEEK);
43
44    size_t i;
45    for(i = 0; i < 256; i++) {
46            if(strcmp(&msgBuffer[i], "\0") == 0)
47            break;
48    }
49
50    // Read the message into msgBuffer
51    msgLength = recv(socketFD, msgBuffer, i + 1, 0);
52    if (msgLength < 0)
53        ERROR(1, "Error reading from socket");
54}
55
56
57int32_t
58ClientSocket(const char* serverName, const char* serverPort)
59{
60    int32_t socketFD;
61    int32_t portNumber;
62
63    struct sockaddr_in serv_addr;
64    struct hostent *server;
65   
66    server = gethostbyname(serverName);
67    if(server == NULL)
68        ERROR(1, "No server found by that hostname.");
69
70    portNumber = atoi(serverPort);
71
72    socketFD = socket(AF_INET, SOCK_STREAM, 0);
73    if(socketFD < 0)
74        ERROR(1, "Error opening socket");
75
76    memset((void *) &serv_addr, 0, sizeof(serv_addr));
77    serv_addr.sin_family = AF_INET;
78    serv_addr.sin_port = htons(portNumber);
79    memcpy((char *) &serv_addr.sin_addr.s_addr, (char *) server->h_addr, \
80            server->h_length);
81
82    if(connect(socketFD, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
83        ERROR(1, "Error connecting to remote socket.");
84
85    return socketFD;
86}
87
88   
89/* TODO I'm fairly certain this function is unnecessary, see function below for more details...
90int32_t
91SendMessage(int32_t socketFD, char* message)
92{
93     
94    // TODO explain this. What, exactly, does the below line do and how does it
95    // affect the rest of the function?
96    strcat(message, "\0000");
97
98    ssize_t numSentBytes = send(socketFD, message, (strlen(message) + 1), 0);
99    if(numSentBytes < 0) {
100        ERROR(1, "Error sending to server.");
101    }
102    else if(numSentBytes == 0) {
103        LOG("socket_comm::SendMessage - Server closed the socket.\n");
104    }
105   
106    return numSentBytes;
107}
108*/
109
110// TODO this function is here to handle calls to send const char* messages. Note
111// that the std::string.c_str() function auto-appends a null character at the
112// end of the cstring, so the strcat function call in the previous function
113// isn't necessary here... I think... although I still don't really understand
114// what exactly that call is for.
115int32_t
116SendMessage(int32_t socketFD, const char* message)
117{
118    ssize_t numSentBytes = send(socketFD, message, (strlen(message) + 1), 0);
119    if(numSentBytes < 0) {
120        ERROR(1, "Error sending to server.");
121    }
122    else if(numSentBytes == 0) {
123        LOG("socket_comm::SendMessage - Server closed the socket.\n");
124    }
125   
126    return numSentBytes;
127}
128
129
130// TODO This function is currently returning 1... always... is this necessary?
131// If we want a fail/success return type, then why aren't we ever returning a
132// failure?
133int32_t
134GetParameter(int32_t socketFD, struct Parameter pList[], \
135        struct Radio_Info *radio_info)
136{
137    char buffer[256];
138    memset(buffer, 0, 256);
139
140    ReadMessage(socketFD, buffer);
141    radio_info->numParameters = atoi(buffer);
142    LOG("socket_comm::GetParameter - Number of parameters: %d\n", \
143            radio_info->numParameters);
144   
145    for(size_t i = 0; i < radio_info->numParameters; i++) {
146        memset(buffer, 0, 256);
147        ReadMessage(socketFD, buffer);
148        LOG("socket_comm::GetParameter - Name: %s\n", buffer);
149        pList[i].name = std::string(buffer);
150   
151        memset(buffer, 0, 256);
152        ReadMessage(socketFD, buffer);
153        LOG("socket_comm::GetParameter - Units: %s\n", buffer);
154        pList[i].units = std::string(buffer);
155
156        memset(buffer, 0, 256);
157        ReadMessage(socketFD, buffer);
158        LOG("socket_comm::GetParameter - Min: %s\n", buffer);
159        pList[i].min = atof(buffer);
160   
161        memset(buffer, 0, 256);
162        ReadMessage(socketFD, buffer);
163        LOG("socket_comm::GetParameter - Max: %s\n", buffer);
164        pList[i].max = atof(buffer);
165   
166        memset(buffer, 0, 256);
167        ReadMessage(socketFD, buffer);
168        LOG("socket_comm::GetParameter - Step: %s\n", buffer);
169        pList[i].step = atof(buffer);
170   
171        memset(buffer, 0, 256);
172        ReadMessage(socketFD, buffer);
173        LOG("socket_comm::GetParameter - Value: %s\n", buffer);
174        pList[i].value = atof(buffer);
175    }
176
177    return 1;
178}
179
180
181// TODO if we are just returing fail/success here, then why not return a bool
182// instead of an entire 32 bit integer?  Seems wasteful.
183int32_t
184GetRequest(int32_t socketFD, struct Parameter pList[], struct Radio_Info *radio_info)
185{
186    char buffer[256];
187    memset(buffer, 0, 256);
188   
189    ReadMessage(socketFD, buffer);
190
191    if(strcmp(buffer, "val") != 0) {
192        LOG("socket_comm::GetRequest - Unexpected control data received.\n\n");
193        return 0;
194    }
195
196    LOG("socket_comm::GetRequest - Getting parameters.\n\n");
197    GetParameter(socketFD, pList, radio_info);
198
199    return 1;
200}
201
202
203int32_t
204AcceptTCPConnection(int32_t serverSock)
205{
206    struct sockaddr_in echoClientAddr;
207
208    uint32_t clientLength = sizeof(echoClientAddr);
209
210    int32_t clientSocket = accept(serverSock, NULL, NULL);
211    if(clientSocket < 0) {
212        LOG("ALERT: Could not establish connection with client socket.\n");
213        return -1;
214    }
215    //LOG("Handling client %s\n", inet_ntoa(echoClientAddr.sin_addr));
216
217    return clientSocket;
218}
219
220
221int32_t
222CreateTCPServerSocket(uint16_t port)
223{
224    struct sockaddr_in echoServerAddr;
225
226    int32_t localSocket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
227    if (localSocket < 0)
228        ERROR(1, "socket() failed\n");
229     
230    /* Construct the local address structure */
231    memset(&echoServerAddr, 0, sizeof(echoServerAddr));
232    echoServerAddr.sin_family = AF_INET;
233    echoServerAddr.sin_addr.s_addr = htonl(INADDR_ANY);
234    echoServerAddr.sin_port = htons(port);
235
236    /* Bind to the local address */
237    if(bind(localSocket, (struct sockaddr *) &echoServerAddr, \
238            sizeof(echoServerAddr)) < 0)
239        ERROR(1, "bind() failed\n");
240
241    /* Mark the socket so it will listen for incoming connections */
242    if(listen(localSocket, 5) < 0)
243        ERROR(1, "listen() failed\n");
244
245    return localSocket;
246}
247
248int32_t
249InitializeTCPServerPort(int32_t servSock)
250{
251    int32_t rc, on = 1;
252
253    rc = setsockopt(servSock, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof(on));
254    if(rc < 0) {
255        shutdown(servSock, 2);
256        close(servSock);
257        ERROR(1,"setsockopt() failed\n");
258    }
259
260    rc = ioctl(servSock, FIONBIO, (char*)&on);
261    if(rc < 0) {
262        shutdown(servSock, 2);
263        close(servSock);
264        ERROR(1,"ioctl() failed\n");
265    }
266
267    return 1;
268}
Note: See TracBrowser for help on using the browser.