Beispiel #1
0
MX_EXPORT mx_status_type
mxi_isobus_command( MX_ISOBUS *isobus,
		long isobus_address,
		char *command,
		char *response,
		size_t max_response_length,
		long maximum_retries,
		unsigned long isobus_flags )
{
	static const char fname[] = "mxi_isobus_command()";

	MX_RECORD *interface_record;
	long gpib_address;
	char local_command_buffer[100];
	char *command_ptr;
	size_t length;
	long i, j, rs232_retries;
	unsigned long wait_ms, num_input_bytes_available;
	mx_bool_type error_occurred;
	mx_status_type mx_status;

	if ( isobus == (MX_ISOBUS *) NULL ) {
		return mx_error( MXE_NULL_ARGUMENT, fname,
		"The MX_ISOBUS pointer passed was NULL." );
	}
	if ( command == (char *) NULL ) {
		return mx_error( MXE_NULL_ARGUMENT, fname,
		"The command pointer passed was NULL." );
	}

	interface_record = isobus->isobus_interface.record;

	if ( interface_record == (MX_RECORD *) NULL ) {
		return mx_error( MXE_CORRUPT_DATA_STRUCTURE, fname,
	    "The interface record pointer for ISOBUS interface '%s' is NULL.",
			isobus->record->name );
	}

	/* Format the command to be sent. */

	if ( isobus_address < 0 ) {
		command_ptr = command;
	} else {
		command_ptr = local_command_buffer;

		snprintf( local_command_buffer, sizeof(local_command_buffer),
			"@%ld%s", isobus_address, command );
	}

	if ( maximum_retries < 0 ) {
		maximum_retries = LONG_MAX;
	}

	error_occurred = FALSE;

	for ( i = 0; i <= maximum_retries; i++ ) {

		if ( i > 0 ) {
			mx_info( "ISOBUS interface '%s' command retry #%ld.",
				isobus->record->name, i );
		}

		/* Send the command and get the response. */

		if ( isobus_flags & MXF_ISOBUS_DEBUG ) {

			MX_DEBUG(-2,("%s: sending command '%s' to '%s'.",
			    fname, command_ptr, isobus->record->name));
		}

		error_occurred = FALSE;

		if ( interface_record->mx_class == MXI_RS232 ) {
			mx_status = mx_rs232_putline( interface_record,
						command_ptr, NULL, 0 );

			if ( mx_status.code != MXE_SUCCESS )
				return mx_status;

			if ( response != NULL ) {
				/* Wait for the response. */

				rs232_retries = 50;
				wait_ms = 100;

				for ( j = 0; j <= rs232_retries; j++ ) {

					/* See if the first character
					 * has arrived.
					 */

					mx_status =
					  mx_rs232_num_input_bytes_available(
						interface_record,
						&num_input_bytes_available );

					if ( mx_status.code != MXE_SUCCESS ) {
						/* Exit the for(j) loop. */

						break;  
					}

					if ( num_input_bytes_available > 0 ) {
						/* Exit the for(j) loop. */

						break;  
					}
				}

				if ( mx_status.code != MXE_SUCCESS ) {
					error_occurred = TRUE;
				} else {
					/* Read in the response. */

					mx_status = mx_rs232_getline(
						interface_record, response,
						max_response_length, NULL, 0);

					if ( mx_status.code != MXE_SUCCESS ) {
						error_occurred = TRUE;
					} else {
						/* Remove any trailing carriage
						 * return characters.
						 */

						length = strlen( response );

						if (length <
							max_response_length )
						{
							if ( response[length-1]
								== MX_CR )
							{
							    response[length-1]
								= '\0';
							}
						}
					}
				}
			}
		} else {	/* GPIB */

			gpib_address = isobus->isobus_interface.address;

			mx_status = mx_gpib_putline(
						interface_record, gpib_address,
						command_ptr, NULL, 0 );

			if ( mx_status.code != MXE_SUCCESS )
				return mx_status;

			if ( response != NULL ) {
				mx_status = mx_gpib_getline(
					interface_record, gpib_address,
					response, max_response_length, NULL, 0);

				if ( mx_status.code != MXE_SUCCESS ) {
					error_occurred = TRUE;
				}
			}
		}

		if ( error_occurred == FALSE ) {

			/* If the first character in the response is a
			 * question mark '?', then an error occurred.
			 */

			if ( response != NULL ) {
				if ( response[0] == '?' ) {

					mx_status = mx_error(
						MXE_DEVICE_ACTION_FAILED, fname,
			"The command '%s' to ISOBUS interface '%s' failed.  "
			"Controller error message = '%s'", command_ptr,
					isobus->record->name, response );

					error_occurred = TRUE;
				} else {
					if ( isobus_flags & MXF_ISOBUS_DEBUG )
					{
						MX_DEBUG(-2,("%s: received "
						"response '%s' from '%s'",
							fname, response,
							isobus->record->name ));
					}
				}
			}
		}

		if ( error_occurred == FALSE ) {
			break;		/* Exit the for() loop. */
		}
	}

	if ( error_occurred ) {
		return mx_error( MXE_TIMED_OUT, fname,
	"The command '%s' to ISOBUS interface '%s' is still failing "
	"after %ld retries.  Giving up...", command_ptr,
				isobus->record->name,
				maximum_retries );
	} else {
		return MX_SUCCESSFUL_RESULT;
	}
}
Beispiel #2
0
int
motor_gpib_fn( int argc, char *argv[] )
{
	static const char cname[] = "gpib";

	MX_RECORD *record;
	int cmd_type, status, address;
	size_t length;
	mx_status_type mx_status;

	static char usage[] =
		"\n"
		"Usage: gpib 'record_name' address getline\n"
		"       gpib 'record_name' address putline \"text to send\"\n"
		"       gpib 'record_name' address command \"text to send\"\n"
		"       gpib 'record_name' address cmd \"text to send\"\n\n";

	if ( argc <= 4 ) {
		fputs( usage, output );
		return FAILURE;
	}

	record = mx_get_record( motor_record_list, argv[2] );

	if ( record == NULL ) {
		fprintf( output, "\n%s: There is no record named '%s'.\n\n",
				cname, argv[2] );
		return FAILURE;
	}

	if ( ( record->mx_superclass != MXR_INTERFACE )
	  || ( record->mx_class != MXI_GPIB ) )
	{
		fprintf( output, "\n%s: Record '%s' is not an GPIB port.\n\n",
				cname, argv[2] );
		return FAILURE;
	}

	address = atoi( argv[3] );

	length = strlen( argv[4] );

	if ( strncmp( "getline", argv[4], max(4,length) ) == 0 ) {
		cmd_type = GPIB_GETLINE_CMD;

	} else if ( strncmp( "putline", argv[4], max(1,length) ) == 0 ) {
		cmd_type = GPIB_PUTLINE_CMD;

	} else if ( strncmp( "command", argv[4], max(1,length) ) == 0 ) {
		cmd_type = GPIB_COMMAND_CMD;

	} else if ( strncmp( "cmd", argv[4], max(1,length) ) == 0 ) {
		cmd_type = GPIB_COMMAND_CMD;

	} else {
		fputs( usage, output );
		return FAILURE;
	}

	if ( cmd_type == GPIB_GETLINE_CMD ) {
		if ( argc != 5 ) {
			fputs( usage, output );
			return FAILURE;
		}
	} else {
		if ( argc != 6 ) {
			fputs( usage, output );
			return FAILURE;
		}
	}

	/* Both putline and command send a string here. */

	if ( ( cmd_type == GPIB_PUTLINE_CMD )
	  || ( cmd_type == GPIB_COMMAND_CMD ) )
	{
		mx_status = mx_gpib_putline( record, address,
					argv[5], NULL, GPIB_DEBUG );

		if ( mx_status.code != MXE_SUCCESS )
			return FAILURE;
	}

	switch( cmd_type ) {
	case GPIB_PUTLINE_CMD:

		/* Putline is done at this point. */

		return SUCCESS;

	case GPIB_GETLINE_CMD:

		status = motor_gpib_readline( record, address );

		if ( status == FAILURE ) {
			fprintf( output,
			"gpib: No new response is available.\n" );

			return FAILURE;
		}
		break;

	case GPIB_COMMAND_CMD:

		mx_msleep(500);

		status = motor_gpib_readline( record, address );

		if ( status == FAILURE ) {
			fprintf( output,
			"gpib: No response is available.\n" );

			return FAILURE;
		}
		break;
	default:
		fprintf( output,
		"gpib: Unrecognized command line.\n" );
		return FAILURE;
	}
	return SUCCESS;
}