I wrote some code to perform several functions. But I lost control of it. puzzling with some of the gaps.
1. int receivePacket()
- I have to get the data here what I have received from the client in UDP. Then perform ScheduleQuery and all other functions.
2. transmitPacket()
- After performing AdvanceQueryCore()- I will be having txBuf, I need to send this back to the Client again.
Can we use two sendto() in UDP programming?
Code:
#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#define MAXSIZE 255
#define SRC_PORT 5000
#define DST_PORT 32000
#define RX_BUF_SIZE 1024
#define TX_BUF_SIZE 1024
void DieWithError(char *errorMessage)
{
DieWithError(errorMessage);
exit(0);
}
void init(QueryCore* qCore);
void run(QueryCore* qCore);
int sock;
struct sockaddr_in servAddr;
struct sockaddr_in clntAddr;
socklen_t cliAddrLen;
char recBuffer[MAXSIZE];
int recvMsgSize;
int i;
int main()
{
printf("Initializing query core\n");
QueryCore qCore;
init(&qCore);
printf("Launching sink node \n");
/* Create socket for sending/receiving datagrams */
if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
DieWithError("socket() failed");
/* Construct address structure */
memset(&servAddr, 0, sizeof(servAddr));
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
servAddr.sin_port = htons(SRC_PORT);
memset(&clntAddr, 0, sizeof(clntAddr));
clntAddr.sin_family = AF_INET;
clntAddr.sin_addr.s_addr = inet_addr("192.168.1.1");
clntAddr.sin_port = htons(DST_PORT);
/* Bind to the local address */
if (bind(sock, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0)
DieWithError("bind() failed");
for (;;) /* Run forever */
{
printf("Listening on UDP:5000 \n");
/* Set the size of the in-out parameter */
cliAddrLen = sizeof(clntAddr);
/* Block until receive message from a client */
if ((recvMsgSize = recvfrom(sock, recBuffer, MAXSIZE, 0,(struct sockaddr *) &clntAddr, &cliAddrLen)) < 0)
DieWithError("recvfrom() failed") ;
printf("Handling Client: %s\n", inet_ntoa(clntAddr.sin_addr));
printf("Received:");
for(i = 0; recBuffer[i] != '\0'; ++i)
printf("%c",recBuffer[i]);
printf("\n");
/* Send response datagram back to the client */
unsigned char respBuffer[] = {255, 255, 255, 255, 4, 'Y', 'E', 'S'};
if (sendto(sock, respBuffer, sizeof(respBuffer), 0, (struct sockaddr *) & clntAddr, sizeof(clntAddr)) < 0)
DieWithError("sendto() failed");
}
run(&qCore);
/* NOT REACHED */
}
void init(QueryCore* qCore)
{
time_t t;
srand((unsigned) time(&t));
initQueryCore(qCore, AM_SINK);
qCore->getSensorValue = &getSensorValue;
qCore->isStaticAttribute = &isStaticAttribute;
qCore->getStaticAttributeValue = &getStaticAttributeValue;
qCore->act = &act;
}
bool packetAvailable()
{
return true;
}
int receivePacket(unsigned char* rxBuf)
{
return 0;
}
bool transmitPacket(unsigned char* txBuf, int len)
{
return true;
}
void run(QueryCore* qCore)
{
while(true)
{
if (packetAvailable())
{
unsigned char rxBuf[RX_BUF_SIZE];
if (receivePacket(rxBuf) > 0)
{
// check the packet type
switch(rxBuf[0])
{
case PT_QUERY:
// parse and schedule the received query data packet
scheduleQuery(qCore, rxBuf);
break;
case PT_QUERY_RESULT:
{
// get the id for which this is a result
int queryId = rxBuf[1];
// get the corresponding query object
int qIdx = findRunningQuery(qCore, queryId);
if (qIdx > -1)
{
// add the results to this query
readResultPacket(qCore, rxBuf, &qCore->queries[qIdx]);
}
break;
}
case PT_CANCEL_QUERY:
{
cancelQuery(qCore,rxBuf[1]);
break;
}
}
}
}
if (advanceQueryCore(qCore, 1))
{
while (!queueIsEmpty(&qCore->packetQueue))
{
PacketToSend* packet = queuePeekHead(&qCore->packetQueue);
uint16 receiverId = packet->receivers[packet->curPos];
unsigned char txBuf[TX_BUF_SIZE];
int len;
if (packet->sendResults)
len = createQueryPacket(qCore, packet->query, txBuf);
else
len = createResultPacket(qCore, packet->query, txBuf);
transmitPacket(txBuf, len);
queueNext(&qCore->packetQueue);
}
}
sleep(20);
}
}