//
// udp_server.c
//

#include <stdio.h>
#include <memory.h>
#include <unistd.h>
#include <strings.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define SERV_UDP_PORT  5943

extern int error;

struct message
{
        char requestseq[5];
        char protocol[4];
        int  discover;
        char callsignal[5];
};

main(int argc, char *argv[])
{
	int    sockfd;
	struct sockaddr_in  cli_addr, serv_addr, peer_addr;
	int    msg_len, clilen, peer_len;
	struct message my_msg;
	char   my_message[100];

	//
	// open a UDP socket
	//
	if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
		printf("server: can't open datagram socket\n");
                exit(1);
        }

	/*
	 * bind specified local address
	 */
	bzero((char *) &serv_addr, sizeof(serv_addr));
	serv_addr.sin_family      = AF_INET;
	serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	serv_addr.sin_port        = htons(SERV_UDP_PORT);

	if (bind(sockfd, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) < 0) {
		printf("server: can't bind to local address\n");
                exit(1);
        }

	printf("server: after bind()...\n");

	clilen = sizeof(cli_addr);
        msg_len = recvfrom(sockfd, (char *)&my_msg, sizeof(my_msg), 0, 
			   (struct sockaddr *) &cli_addr, &clilen);

    peer_len = sizeof(struct sockaddr_in);
    errno = getpeername(sockfd, (sockaddr *) &peer_addr, &peer_len);
    sprintf(my_message, "client socket info [%d.%d.%d.%d:%d]\n", 
                    ((peer_addr.sin_addr.s_addr & (255 << 24)) >> 24),
                    ((peer_addr.sin_addr.s_addr & (255 << 16)) >> 16),
                    ((peer_addr.sin_addr.s_addr & (255 << 8)) >> 8),
                    (peer_addr.sin_addr.s_addr & 255),
                    peer_addr.sin_port);
    printf("my message [%s]\n", my_message);

	printf("* server: client port # [%d]\n", (int) cli_addr.sin_port);
	printf("* server: client IP addr [%s]\n\n", inet_ntoa(cli_addr.sin_addr));

	printf("received msg length == %d (%d) \n", msg_len, sizeof(my_msg));
        printf("requestseq [%s]\n", my_msg.requestseq);
        printf("protocol   [%s]\n", my_msg.protocol);
        printf("discover   [%d]\n", my_msg.discover);
        printf("callsignal [%s]\n", my_msg.callsignal);

	strcpy(my_msg.requestseq, "$$$");
	strcpy(my_msg.protocol, "###");
	my_msg.discover = 999;
	strcpy(my_msg.callsignal, "@@@@");

	/*
	 * send back response
	 */
        sendto(sockfd, (char*) &my_msg, msg_len, 0,
	       (struct sockaddr*) &cli_addr, clilen);
}
