/*
 *  sample program
 *  UDP Server program
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <getopt.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <errno.h>
#define UDPMAX 0xffff

static void help(void);
static int set_udp_socket(int, unsigned long);
int main(int argc ,char *argv[])
{
    char buf[UDPMAX] = {0};
    int opt = 0, sockfd = 0, port = 51237, loop = 1, len = 0;
    struct sockaddr_in from;
    socklen_t addrlen;
    const struct option longopt[] = {
        {"help", 0, 0, 'h'},
        {"port", 1, 0, 'p'},
        {0, 0, 0, 0},
    };

    /* get command option */
    while((opt = getopt_long(argc, argv, "hHp:P:", longopt, NULL)) != -1){
        switch(opt){
        case 'p':
        case 'P':
            port = atoi(optarg);
            break;
        case 'h':
        case 'H':
        case '?':
            help();
            return 0;
        }
    }
    if((port <= 0) || (port > 65535)){
        help();
        return -1;
    }

    /* create socket */
    sockfd = set_udp_socket(port, 0);
    if(sockfd < 0){
        return -1;
    }
    FILE *fp;
    fp = fopen("ZGNaviLaData.csv", "w");

    while(loop){
        addrlen = sizeof(struct sockaddr_in);
        len = recvfrom(sockfd, buf, sizeof(buf), 0,
                (struct sockaddr *)&from, &addrlen);
        if(len < 0){
            perror("recvfrom error");
            break;
        }else if(addrlen == 0){
            continue;    /* unidentified address */
        }
        //fprintf(stdout, "received data(%dbyte) from %s:%d\n",
        //    len, inet_ntoa(from.sin_addr), ntohs(from.sin_port));
        //fprintf(stdout, "%s\n", buf);
	    FILE *fp;
    	fp = fopen("ZGNaviLaData.csv", "w");
        fprintf(fp, "%s\n", buf);
    	fclose(fp);
        if(strncmp(buf, "quit\n", 5) == 0){
            loop = 0;
        }
        memset(buf, 0, len);
    }
    close(sockfd);

    return 0;
}

static void help(void)
{
    fprintf(stdout,
        "Usage: udpserver [-p port]\n"
    );
    return;
}

static int set_udp_socket(int portnum, unsigned long ipaddr)
{
    int sockfd;
    struct sockaddr_in server;

    /* create socket */
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if(sockfd < 0){
        perror("socket error");
        return -1;
    }

    /* set socket address information */
    memset(&server, 0, sizeof(struct sockaddr_in));
    server.sin_family = AF_INET;
    if(ipaddr == 0){
        server.sin_addr.s_addr = htonl(INADDR_ANY);
    }else{
        server.sin_addr.s_addr = htonl(ipaddr);
    }
    server.sin_port = htons(portnum);

    /* bind socket */
    if(bind(sockfd, (struct sockaddr *)&server, sizeof(server)) < 0){
        perror("bind error");
        close(sockfd);
        return -1;
    }
    return sockfd;
}