//
// udp_client.c
//

#include <stdio.h>
#include <iostream.h>
#include <memory.h>
#include <unistd.h>
#include <string.h>
#include <strings.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
 
#define SERV_UDP_PORT  5943
#define SERV_HOST_ADDR "128.4.131.63"   /* wheatgrass.cis.udel.edu */
 
struct message
{
  char requestseq[5];
  char protocol[4];
  int  discover;
  char callsignal[5];
};

main(int argc, char *argv[])
{
	int sockfd, msg_len, c_len, err_code;
	struct sockaddr_in  serv_addr, cli_addr;

	struct message mesg, mesg_rsp;

	strcpy(mesg.requestseq , "AAAA");
	strcpy(mesg.protocol,    "BBB");
	mesg.discover =          123;
	strcpy(mesg.callsignal,  "ZZZZ");

	/*
	 * fill in server's IP address and port #
	 */
	bzero((char *) &serv_addr, sizeof(serv_addr));
	serv_addr.sin_family      = AF_INET;
        serv_addr.sin_addr.s_addr = inet_addr(SERV_HOST_ADDR);
        serv_addr.sin_port        = htons(SERV_UDP_PORT);

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

	/*
	 * IP addr == INADDR_ANY ---> system determines an IP address
	 * port # == 0           ---> system assigns a unused port # which
	 *                            is unique on the local system
	 */
	bzero((char *) &cli_addr, sizeof(cli_addr));
	cli_addr.sin_family      = AF_INET;
        cli_addr.sin_addr.s_addr = htonl(INADDR_ANY);
        cli_addr.sin_port        = htons(0);

	/*
	 * bind to ANY local address
	 */
	if (bind(sockfd, (struct sockaddr*) &cli_addr, sizeof(cli_addr)) < 0) {
	  printf("client: can't bind to local address\n");
	  return -1;
        }

// -------------
        c_len = sizeof(struct sockaddr);
        err_code = getsockname(sockfd, (struct sockaddr*) &cli_addr, &c_len);
        if (err_code == 0) {
          cerr << "client: port # " << cli_addr.sin_port << endl;
          printf("client: IP addr [%d.%d.%d.%d]\n",
                  ((cli_addr.sin_addr.s_addr & (255 << 24)) >> 24),
                  ((cli_addr.sin_addr.s_addr & (255 << 16)) >> 16),
                  ((cli_addr.sin_addr.s_addr & (255 << 8)) >> 8),
                  (cli_addr.sin_addr.s_addr & 255));
        }
        else
          cerr << "getsockname() status = " << err_code << endl;
// -------------

	printf("msg length == [%d]\n", sizeof(mesg));

	sendto(sockfd, (char *) &mesg, sizeof(mesg), 0, 
	       (struct sockaddr*) &serv_addr, sizeof(serv_addr));

	msg_len = recvfrom(sockfd, (char *)& mesg_rsp, sizeof(mesg_rsp), 0, 
		           (struct sockaddr*) 0, (int*) 0);

	printf("response back from server [%d] -----------\n", msg_len);
        printf("requestseq [%s]\n", mesg_rsp.requestseq);
        printf("protocol   [%s]\n", mesg_rsp.protocol);
        printf("discover   [%d]\n", mesg_rsp.discover);
        printf("callsignal [%s]\n", mesg_rsp.callsignal);

	close(sockfd);
}
