I've been set a task to write some software to communicate from our embedded linux device to a server. The server that I'm to communicate with uses a strict protocol, the protocol is very obscure and proprietary - I wouldn't like to name it on here as the information could be sensitive to the company I work for.
So the data must be in either the form of 4 bit Nibbles (N), 32 bit unsigned ints (U), 32 bit signed ints (S), 8 bit unsigned ints (X) and chars (C). So for example a simplified login structure might be NNNN-User ID followed by XX-some more data, CCCC-access code. So I need to send NNNNXXCCCC in that order to login.
The data needs to be sent via UDP, and then listen for an acknowledgement on the same port. So the way I've done this is I've written a send_and_receive function, and then coded a struct, to send the struct through to the server.
typedef u_int8_t NN;
typedef u_int8_t X;
typedef int32_t S;
typedef u_int32_t U;
typedef char C;
#pragma pack(1)
typedef struct{
NN user_id[2];
X some_data[2];
C access_code[4];
} LogOnRequest;
I then declare and fill in the information for the struct and send it using this function:
void send_and_receive(void* message, void* reply, int do_send, int expect_reply){
struct sockaddr_in serv_addr;
int sockfd, i, slen=sizeof(serv_addr);
int buflen = BUFLEN;
void* buf = NULL;
if ( (strlen(message)) >= BUFLEN)
err("Message too big");
buf = malloc(buflen);
if ((sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1)
err("socket");
bzero(&serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
if (inet_aton(IP_ADDRESS, &serv_addr.sin_addr)==0)
err("inet_aton() failed\n");
if(do_send == TRUE){
strcpy(buf, message);
if (sendto(sockfd, buf, buflen, 0, (struct sockaddr*)&serv_addr, slen)==-1)
err("sendto()");
}
if (expect_reply == TRUE){
if (recvfrom(sockfd, buf, buflen, 0, (struct sockaddr*)&serv_addr, &slen)==-1)
err("recvfrom()");
}
memcpy(reply, buf, BUFLEN);
close(sockfd);
free(buf);
}
Now when I do this I get no reply, and no notice that the packet has been received on the server. Basically I would like to know if I'm doing this correctly, is there a better way to do it? Would it be possible to do the same thing using bash scripts?
Any feedback would be great, because I'm feeling out of my depth on this one.
if (sendto(sockfd, buf, buflen,will write the complete buffer, even beyond the terminating NUL character.