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

Revision 176, 7.6 KB (checked in by bhilburn, 15 years ago)

Moved three functions from the shell's implementation to the socket library.
Have not yet cleaned them up.

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