/**
 * Set the connection parameters for dlt client
 */
int init_dlt_connect(DltClient *client, const s_parameters *params, int argc, char *argv[]) {
	char id[4];
	if (argc < 2)
		return -1;
	if(params->serial > 0)
	{
		client->serial_mode = 1;
		client->serialDevice = argv[argc - 1];
		dlt_client_setbaudrate(client, params->baudrate);
	}
	else
	{
		client->servIP = argv[argc - 1];
	}
	dlt_set_id(id, ECUID);
	return 0;
}
/**
 * Main function of tool.
 */
int main(int argc, char* argv[])
{
    DltClient       dltclient;
    DltTestclientData dltdata;
    int c,i;
    int index;

    /* Initialize dltdata */
    dltdata.aflag = 0;
    dltdata.sflag = 0;
    dltdata.xflag = 0;
    dltdata.mflag = 0;
    dltdata.vflag = 0;
    dltdata.yflag = 0;
    dltdata.ovalue = 0;
    dltdata.fvalue = 0;
    dltdata.evalue = 0;
    dltdata.bvalue = 0;
    dltdata.nvalue = 10000;
    dltdata.ohandle= -1;

    dltdata.running_test = 0;

    for (i=0; i<DLT_TESTCLIENT_NUM_TESTS; i++)
    {
        dltdata.test_counter_macro[i]=0;
        dltdata.test_counter_function[i]=0;
    }

    dltdata.tests_passed = 0;
    dltdata.tests_failed = 0;

    dltdata.bytes_received = 0;
    dltdata.time_elapsed = dlt_uptime();

    dltdata.last_value = 0;
    dltdata.count_received_messages = 0;
    dltdata.count_not_received_messages = 0;


    dltdata.sock = -1;

    /* Fetch command line arguments */
    opterr = 0;

    while ((c = getopt (argc, argv, "vashyxmf:o:e:b:n:")) != -1)
    {
        switch (c)
        {
        case 'v':
        {
            dltdata.vflag = 1;
            break;
        }
        case 'a':
        {
            dltdata.aflag = 1;
            break;
        }
        case 's':
        {
            dltdata.sflag = 1;
            break;
        }
        case 'x':
        {
            dltdata.xflag = 1;
            break;
        }
        case 'm':
        {
            dltdata.mflag = 1;
            break;
        }
        case 'h':
        {
            usage();
            return -1;
        }
        case 'y':
        {
            dltdata.yflag = 1;
            break;
        }
        case 'f':
        {
            dltdata.fvalue = optarg;
            break;
        }
        case 'o':
        {
            dltdata.ovalue = optarg;
            break;
        }
        case 'e':
        {
            dltdata.evalue = optarg;
            break;
        }
        case 'b':
        {
            dltdata.bvalue = atoi(optarg);
            break;
        }
        case 'n':
        {
            dltdata.nvalue = atoi(optarg);
            break;
        }
        case '?':
        {
            if (optopt == 'o' || optopt == 'f' || optopt == 't')
            {
                fprintf (stderr, "Option -%c requires an argument.\n", optopt);
            }
            else if (isprint (optopt))
            {
                fprintf (stderr, "Unknown option `-%c'.\n", optopt);
            }
            else
            {
                fprintf (stderr, "Unknown option character `\\x%x'.\n",optopt);
            }
            /* unknown or wrong option used, show usage information and terminate */
            usage();
            return -1;
        }
        default:
        {
            abort ();
        }
        }
    }

    /* Initialize DLT Client */
    dlt_client_init(&dltclient, dltdata.vflag);

    /* Register callback to be called when message was received */
    dlt_client_register_message_callback(dlt_testclient_message_callback);

    /* Setup DLT Client structure */
    dltclient.serial_mode = dltdata.yflag;

    if (dltclient.serial_mode==0)
    {
        for (index = optind; index < argc; index++)
        {
            dltclient.servIP = argv[index];
        }

        if (dltclient.servIP == 0)
        {
            /* no hostname selected, show usage and terminate */
            fprintf(stderr,"ERROR: No hostname selected\n");
            usage();
            dlt_client_cleanup(&dltclient,dltdata.vflag);
            return -1;
        }
    }
    else
    {
        for (index = optind; index < argc; index++)
        {
            dltclient.serialDevice = argv[index];
        }

        if (dltclient.serialDevice == 0)
        {
            /* no serial device name selected, show usage and terminate */
            fprintf(stderr,"ERROR: No serial device name specified\n");
            usage();
            return -1;
        }

        dlt_client_setbaudrate(&dltclient,dltdata.bvalue);
    }

    /* initialise structure to use DLT file */
    dlt_file_init(&(dltdata.file),dltdata.vflag);

    /* first parse filter file if filter parameter is used */
    dlt_filter_init(&(dltdata.filter),dltdata.vflag);

    if (dltdata.fvalue)
    {
        if (dlt_filter_load(&(dltdata.filter),dltdata.fvalue,dltdata.vflag)<0)
        {
            dlt_file_free(&(dltdata.file),dltdata.vflag);
            return -1;
        }

        dlt_file_set_filter(&(dltdata.file),&(dltdata.filter),dltdata.vflag);
    }

    /* open DLT output file */
    if (dltdata.ovalue)
    {
        dltdata.ohandle = open(dltdata.ovalue,O_WRONLY|O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); /* mode: wb */

        if (dltdata.ohandle == -1)
        {
            dlt_file_free(&(dltdata.file),dltdata.vflag);
            fprintf(stderr,"ERROR: Output file %s cannot be opened!\n",dltdata.ovalue);
            return -1;
        }
    }

    if (dltdata.evalue)
    {
        dlt_set_id(dltdata.ecuid,dltdata.evalue);
    }
    else
    {
        dlt_set_id(dltdata.ecuid,DLT_TESTCLIENT_ECU_ID);
    }

    /* Connect to TCP socket or open serial device */
    if (dlt_client_connect(&dltclient, dltdata.vflag)!=-1)
    {
        dltdata.sock = dltclient.sock;

        /* Dlt Client Main Loop */
        dlt_client_main_loop(&dltclient, &dltdata, dltdata.vflag);

        /* Dlt Client Cleanup */
        dlt_client_cleanup(&dltclient,dltdata.vflag);
    }

    /* dlt-receive cleanup */
    if (dltdata.ovalue)
    {
        close(dltdata.ohandle);
    }

    dlt_file_free(&(dltdata.file),dltdata.vflag);

    dlt_filter_free(&(dltdata.filter),dltdata.vflag);

    return 0;
}
/**
 * Main function of tool.
 */
int main(int argc, char* argv[])
{
    DltClient      dltclient;
    DltReceiveData dltdata;
    int c;
    int index;

    /* Initialize dltdata */
    dltdata.vflag = 0;
    dltdata.yflag = 0;
    dltdata.evalue = 0;
    dltdata.bvalue = 0;

    dltdata.avalue = 0;
    dltdata.cvalue = 0;
    dltdata.svalue = 0;
    dltdata.mvalue = 0;
    dltdata.xvalue = 0;
    dltdata.tvalue = 1000;
    dltdata.lvalue = -1;
    dltdata.rvalue = -1;
    dltdata.dvalue = -1;
    dltdata.fvalue = -1;
    dltdata.ivalue = -1;
    dltdata.oflag = -1;
    dltdata.gflag = -1;

    /* Fetch command line arguments */
    opterr = 0;

    while ((c = getopt (argc, argv, "vhye:b:a:c:s:m:x:t:l:r:d:f:i:og")) != -1)
        switch (c)
        {
        case 'v':
			{
            	dltdata.vflag = 1;
            	break;
			}
        case 'h':
			{
            	usage();
            	return -1;
			}
        case 'y':
			{
            	dltdata.yflag = 1;
            	break;
			}
        case 'e':
			{
            	dltdata.evalue = optarg;
            	break;
			}
        case 'b':
			{
            	dltdata.bvalue = atoi(optarg);
            	break;
			}

        case 'a':
			{
            	dltdata.avalue = optarg;
            	break;
			}
        case 'c':
			{
            	dltdata.cvalue = optarg;
            	break;
			}
        case 's':
			{
            	dltdata.svalue = atoi(optarg);
            	break;
			}
        case 'm':
			{
            	dltdata.mvalue = optarg;
            	break;
			}
        case 'x':
			{
            	dltdata.xvalue = optarg;
            	break;
			}
        case 't':
			{
            	dltdata.tvalue = atoi(optarg);;
            	break;
			}
        case 'l':
			{
            	dltdata.lvalue = atoi(optarg);;
            	break;
			}
        case 'r':
			{
            	dltdata.rvalue = atoi(optarg);;
            	break;
			}
        case 'd':
			{
            	dltdata.dvalue = atoi(optarg);;
            	break;
			}
        case 'f':
			{
            	dltdata.fvalue = atoi(optarg);;
            	break;
			}
        case 'i':
			{
            	dltdata.ivalue = atoi(optarg);;
            	break;
			}
        case 'o':
			{
            	dltdata.oflag = 1;
            	break;
			}
        case 'g':
			{
            	dltdata.gflag = 1;
            	break;
			}

        case '?':
			{
		        if (optopt == 'o' || optopt == 'f')
				{
		            fprintf (stderr, "Option -%c requires an argument.\n", optopt);
		        }
				else if (isprint (optopt))
				{
		            fprintf (stderr, "Unknown option `-%c'.\n", optopt);
		        }
				else
				{
		            fprintf (stderr, "Unknown option character `\\x%x'.\n",optopt);
				}
		        /* unknown or wrong option used, show usage information and terminate */
		        usage();
		        return -1;
			}
        default:
			{
            	abort ();
                return -1;//for parasoft
			}
        }

    /* Initialize DLT Client */
    dlt_client_init(&dltclient, dltdata.vflag);

    /* Register callback to be called when message was received */
    dlt_client_register_message_callback(dlt_receive_message_callback);

    /* Setup DLT Client structure */
    dltclient.serial_mode = dltdata.yflag;

    if (dltclient.serial_mode==0)
    {
        for (index = optind; index < argc; index++)
        {
            dltclient.servIP = argv[index];
        }

        if (dltclient.servIP == 0)
        {
            /* no hostname selected, show usage and terminate */
            fprintf(stderr,"ERROR: No hostname selected\n");
            usage();
            dlt_client_cleanup(&dltclient,dltdata.vflag);
            return -1;
        }
    }
    else
    {
        for (index = optind; index < argc; index++)
        {
            dltclient.serialDevice = argv[index];
        }

        if (dltclient.serialDevice == 0)
        {
            /* no serial device name selected, show usage and terminate */
            fprintf(stderr,"ERROR: No serial device name specified\n");
            usage();
            return -1;
        }

		dlt_client_setbaudrate(&dltclient,dltdata.bvalue);
    }

    /* initialise structure to use DLT file */
    dlt_file_init(&(dltdata.file),dltdata.vflag);

    /* first parse filter file if filter parameter is used */
    dlt_filter_init(&(dltdata.filter),dltdata.vflag);

    if (dltdata.evalue)
	{
        dlt_set_id(dltdata.ecuid,dltdata.evalue);
    }
	else
	{
        dlt_set_id(dltdata.ecuid,DLT_RECEIVE_ECU_ID);
	}

    /* Connect to TCP socket or open serial device */
    if (dlt_client_connect(&dltclient, dltdata.vflag)!=-1)
    {
    	/* send injection message */
    	if(dltdata.mvalue && dltdata.avalue && dltdata.cvalue)
    	{
    		/* ASCII */
    		printf("Send injection message:\n");
    		printf("AppId: %s\n",dltdata.avalue);
    		printf("ConId: %s\n",dltdata.cvalue);
    		printf("ServiceId: %d\n",dltdata.svalue);
    		printf("Message: %s\n",dltdata.mvalue);
    		/* send control message in ascii */
    		dlt_client_send_inject_msg(&dltclient,dltdata.avalue,dltdata.cvalue,dltdata.svalue,(uint8_t*)dltdata.mvalue,strlen(dltdata.mvalue));
    	}
    	else if(dltdata.xvalue && dltdata.avalue && dltdata.cvalue)
    	{
    		/* Hex */
    		uint8_t buffer[1024];
    		int size = 1024;
    		printf("Send injection message:\n");
    		printf("AppId: %s\n",dltdata.avalue);
    		printf("ConId: %s\n",dltdata.cvalue);
    		printf("ServiceId: %d\n",dltdata.svalue);
    		printf("Message: %s\n",dltdata.xvalue);
    		hexAsciiToBinary(dltdata.xvalue,buffer,&size);
    		printf("Size: %d\n",size);
    		/* send control message in hex */
    		dlt_client_send_inject_msg(&dltclient,dltdata.avalue,dltdata.cvalue,dltdata.svalue,buffer,size);
    	}
    	else if(dltdata.lvalue!=-1 && dltdata.avalue && dltdata.cvalue)
    	{
    		/* log level */
    		printf("Set log level:\n");
    		printf("AppId: %s\n",dltdata.avalue);
    		printf("ConId: %s\n",dltdata.cvalue);
    		printf("Loglevel: %d\n",dltdata.lvalue);
    		/* send control message*/
    		dlt_client_send_log_level(&dltclient,dltdata.avalue,dltdata.cvalue,dltdata.lvalue);
    	}
    	else if(dltdata.rvalue!=-1 && dltdata.avalue && dltdata.cvalue)
    	{
    		/* trace status */
    		printf("Set trace status:\n");
    		printf("AppId: %s\n",dltdata.avalue);
    		printf("ConId: %s\n",dltdata.cvalue);
    		printf("TraceStatus: %d\n",dltdata.rvalue);
    		/* send control message in*/
    		dlt_client_send_trace_status(&dltclient,dltdata.avalue,dltdata.cvalue,dltdata.rvalue);
    	}
    	else if(dltdata.dvalue!=-1)
    	{
    		/* default log level */
    		printf("Set default log level:\n");
    		printf("Loglevel: %d\n",dltdata.dvalue);
    		/* send control message in*/
    		dlt_client_send_default_log_level(&dltclient,dltdata.dvalue);
    	}
    	else if(dltdata.rvalue!=-1)
    	{
    		/* default trace status */
    		printf("Set default trace status:\n");
    		printf("TraceStatus: %d\n",dltdata.rvalue);
    		/* send control message in*/
    		dlt_client_send_default_trace_status(&dltclient,dltdata.rvalue);
    	}
    	else if(dltdata.ivalue!=-1)
    	{
    		/* timing pakets */
    		printf("Set timing pakets:\n");
    		printf("Timing packets: %d\n",dltdata.ivalue);
    		/* send control message in*/
    		dlt_client_send_timing_pakets(&dltclient,dltdata.ivalue);
    	}
    	else if(dltdata.oflag!=-1)
    	{
    		/* default trace status */
    		printf("Store config\n");
    		/* send control message in*/
    		dlt_client_send_store_config(&dltclient);
    	}
    	else if(dltdata.gflag!=-1)
    	{
    		/* reset to factory default */
    		printf("Reset to factory default\n");
    		/* send control message in*/
    		dlt_client_send_reset_to_factory_default(&dltclient);
    	}

        /* Dlt Client Main Loop */
        //dlt_client_main_loop(&dltclient, &dltdata, dltdata.vflag);

    	/* Wait timeout */
    	usleep(dltdata.tvalue*1000);

        /* Dlt Client Cleanup */
        dlt_client_cleanup(&dltclient,dltdata.vflag);
    }

    dlt_file_free(&(dltdata.file),dltdata.vflag);

    dlt_filter_free(&(dltdata.filter),dltdata.vflag);

    return 0;
}