/* broadcast_server.c */
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netdb.h>
#include <errno.h>
#include <unistd.h>
#include <time.h>

/*Set port number*/
#define SEND_PORT 57188		//client listen port
#define REV_PORT 54321		//server listen port

int main(){
	int send_sockfd, rev_sockfd;
	struct sockaddr_in send_server_addr, send_client_addr, rev_server_addr, rev_client_addr;
	int so_broadcast = 1;
	char send_buf[32] = "ICPDAS7188E,00 ";
	char *delim = ",";
	char * pch;

	char rev_buf[256];
	socklen_t addrlen = sizeof(rev_client_addr);
	ssize_t size;
	struct timeval timeout={1,0};//3s 

	/*Create an IPv4 UDP socket*/
	if((send_sockfd = socket(PF_INET, SOCK_DGRAM, 0))<0){
		perror("send socket");
		return -1;
	}

	/*Create an IPv4 UDP socket*/
	if((rev_sockfd = socket(PF_INET, SOCK_DGRAM, 0))<0){
		perror("receive socket");
		return -1;
	}

	/*SO_BROADCAST: broadcast attribute*/
	if(setsockopt(send_sockfd, SOL_SOCKET, SO_BROADCAST, &so_broadcast, sizeof(so_broadcast))<0){
		perror("setsockopt");
		return -1;
	}

	send_server_addr.sin_family = AF_INET; /*IPv4*/
	send_server_addr.sin_port = htons(INADDR_ANY); /*All the port*/
	send_server_addr.sin_addr.s_addr = htonl(INADDR_BROADCAST); /*Broadcast address*/

	if((bind(send_sockfd, (struct sockaddr*)&send_server_addr, sizeof(struct sockaddr))) != 0){
		perror("bind");
		return -1;
	}

	send_client_addr.sin_family = AF_INET; /*IPv4*/
	send_client_addr.sin_port = htons(SEND_PORT);  /*Set port number*/
	send_client_addr.sin_addr.s_addr = htonl(INADDR_BROADCAST); /*The broadcast address*/
	int clientlen = sizeof(send_client_addr);


	rev_server_addr.sin_family = AF_INET;
	rev_server_addr.sin_port = htons(REV_PORT);
	rev_server_addr.sin_addr.s_addr = htonl(INADDR_ANY); /*All the host*/

	if(setsockopt(rev_sockfd, SOL_SOCKET, SO_REUSEADDR, &so_broadcast, sizeof(so_broadcast))<0){
                perror("setsockopt");
                return -1;
        }

	if(setsockopt(rev_sockfd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout))<0){
                perror("setsockopt");
                return -1;
        }

        if(bind(rev_sockfd, (struct sockaddr *)&rev_server_addr, sizeof(struct sockaddr)) != 0){
                perror("bind");
                return -1;
        }

	//send messaage
	if((sendto(send_sockfd, send_buf, strlen(send_buf), 0, (struct sockaddr*)&send_client_addr, (socklen_t)clientlen)) < 0){
		perror("sendto");
		return -1;
	} 

	close(send_sockfd);


	printf("List modules in submask\n");
	while(1)
        {
		memset(rev_buf, 0, 256); /*Clean up the buffer*/
		size = 0;

		/*Use recvfrom() to receive the messages from server*/
		size = recvfrom(rev_sockfd, rev_buf, 256, 0, (struct sockaddr *)&rev_client_addr, &addrlen);
		if(size<0){
			//perror("recvfrom");
			break;
		}

		pch = strtok(rev_buf, delim);

		while (pch != NULL)
		{
			if(*pch == 'N')
				printf ("%-25.24s\n",pch);
			if((*pch == 'I' && *(pch+1) == 'P') || *pch == 'M' || *pch == 'G')
				printf ("%-20.23s",pch);

			pch = strtok(NULL, delim);
		}
		printf("\n");
        }

        close(rev_sockfd);
	return 0;
}
