/*
 * This is sample code generated by rpcgen.
 * These are only templates and you can use them
 * as a guideline for developing your own functions.
 */

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

#include "VXI11.h"
enum DEVICE_FLAGS{
        device_flags_termchrset = 0x80,
        device_flags_end = 0x8,
        device_flags_waitlock = 0x1,
        DEVICE_FLAGS_TERMCHRSET = 0X80,
        DEVICE_FLAGS_END = 0X8,
        DEVICE_FLAGS_WAITLOCK = 0X1
};

long 
device_scan(char *host,char *device)
{
	CLIENT *clnt;
	Create_LinkResp  *result_1;
	Create_LinkParms  create_link_1_arg;
	Device_WriteResp  *result_2;
	Device_WriteParms  device_write_1_arg;
	Device_ReadResp  *result_3;
	Device_ReadParms  device_read_1_arg;
	Device_Error  *result_6;
	Device_GenericParms  device_clear_1_arg;
	Device_Error  *result_7;
	Device_GenericParms  device_remote_1_arg;
	
	printf("Try device:%s ************\n", device);
	
	clnt = clnt_create (host, DEVICE_CORE, DEVICE_CORE_VERSION, "tcp");
	if (clnt == NULL) {
		clnt_pcreateerror (host);
		return -1;
	}
	
	memset((void *) &create_link_1_arg, 0, sizeof(Create_LinkParms));
	create_link_1_arg.clientId = (long) clnt;
	create_link_1_arg.lockDevice = 0;  /* do not try to lock the device */
	create_link_1_arg.lock_timeout = 0;/* if device is locked, forget it */
	create_link_1_arg.device=device;
	
	result_1 = create_link_1(&create_link_1_arg, clnt);
	if (result_1 == (Create_LinkResp *) NULL) {
		clnt_perror (clnt, "create_link call failed");
		clnt_destroy (clnt);
		return 1;
	}
	printf("link created to %s \n",	create_link_1_arg.device );
	printf("\t Error code:%ld\n\t LinkID:%ld\n\t port %hd\n\t MaxRecvSize:%ld\n",
	       result_1->error, result_1->lid ,
	       result_1->abortPort, result_1->maxRecvSize);
	
	{
		device_remote_1_arg.lid=result_1->lid;
		device_remote_1_arg.io_timeout=0;
		memset((char *) &device_remote_1_arg, 0, sizeof(Device_GenericParms));
		result_7 = device_remote_1(&device_remote_1_arg, clnt);
		if (result_7 == (Device_Error *) NULL) {
			clnt_perror (clnt, "device_remote call failed");
			clnt_destroy (clnt);
			return -1;
		}
		else{
			printf("Is the device  remote? RC:%ld\n",result_7->error);
		}
	}
	
	{
		memset((char *) &device_write_1_arg, 
		       0, 
		       sizeof(Device_WriteParms));
		device_write_1_arg.lid=result_1->lid;
		device_write_1_arg.data.data_val = "*RST;*IDN?;\n";
		device_write_1_arg.data.data_val = "*IDN?;\n"; /* for TDS3000 */
		device_write_1_arg.flags = DEVICE_FLAGS_END; /* no more data left */
		device_write_1_arg.data.data_len= 
			strlen((const char *) device_write_1_arg.data.data_val);
		
		result_2 = device_write_1(&device_write_1_arg, clnt);
		if (result_2 == (Device_WriteResp *) NULL) {
			clnt_perror (clnt, "device_write call failed");
			clnt_destroy (clnt);
			return -1;
		}
		else if (result_2->error == 15){
			printf("device %s does not exist.\n",device);
			clnt_destroy (clnt);
			return 1;
		}
		else{
			printf("wrote %s\n", device_write_1_arg.data.data_val);
		}
		printf("\t Error code:%ld\n\t Size:%ld\n",
		       result_2->error,  
		       result_2->size);
	}
	
	sleep(1);
	
	printf("start to read\n");{
		
		device_read_1_arg.lid=result_1->lid;
		device_read_1_arg.requestSize=255;
		device_read_1_arg.io_timeout=5;
		device_read_1_arg.lock_timeout=0;
		device_read_1_arg.flags |= DEVICE_FLAGS_TERMCHRSET;
		device_read_1_arg.termChar='\n';
		
		while(1) { /*Allow for very long or infinite timeout*/
			result_3 = device_read_1(&device_read_1_arg, clnt);
			if(result_3->error!=15  /* 15: No device */
			   || result_3->data.data_len>0) break;
			sleep(1);
		}
		if(result_3->data.data_len >0){
			printf("%d bytes data read:%s\n",result_3->data.data_len,result_3->data.data_val);
		}
		else{
			printf("%s returns nodata.\n",device);
			clnt_destroy (clnt);
			return -1;
		}
	}
	sleep(1);
	
	printf("Clear\n");{
		device_clear_1_arg.lid=result_1->lid;
		device_clear_1_arg.io_timeout=0;
		result_6 = device_clear_1(&device_clear_1_arg, clnt);
		if (result_6 == (Device_Error *) NULL) {
			clnt_perror (clnt, "device_clear call failed");
		}
	}
	
	if (clnt != NULL) clnt_destroy (clnt);
        return 0;
}


int
main (int argc, char *argv[])
{
	char *host;
	char device[255];
	char cmd[255];
	long i,status,result;
	
	if (argc < 2) {
		printf ("usage: %s server_host\n", argv[0]);
		exit (1);
	}
	host = argv[1];
	
	sprintf(cmd,"/usr/sbin/rpcinfo -p %s",host);
	printf("\n Get RPC info\n");
	result=system(cmd);
	if (result==0){
		printf("Done\n");
	}
	else{
		printf("rpcinf failed");
		exit(-1);
	}
	// check if host has VXI11-Core
	sprintf(cmd,"/usr/sbin/rpcinfo -t %s %u", host, DEVICE_CORE);
	result=system(cmd);
	if (result == 0){
          printf("VXI11-core service is ruuning \n");
	}
	else{
		printf("VXI11-core service is NOT available \n");
		exit(-1);
	}
        
	printf("\n START scanning.\n");
	
	status=-1;
	
	sprintf(device,"inst0");
	status=device_scan (host, device);
	if (status == 0)  exit (0);

	sprintf(device,"gpib0");
	status=device_scan (host, device);
	if (status == 0)  exit (0);
	
	if (status != 0){
		for(i=0;i<31;i++){
			sprintf(device,"inst0,%-d",i);
			status=device_scan (host, device);
			if (status == 0)  exit(0);
		}
	}

	for(i=0;i<31;i++){
		sprintf(device,"gpib0,%-ld",i);
		status=device_scan (host, device);
		if (status == 0)  exit (0);
	}
	
	exit (0);
}
