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

Revision 187, 6.5 KB (checked in by bhilburn, 15 years ago)

Abandoning the RemoteComponent? struct; migrating to a simple socketFD
and boolean field.

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