Esempio n. 1
0
static int
audin_on_data_received(IWTSVirtualChannelCallback * pChannelCallback,
	uint32 cbSize,
	char * pBuffer)
{
	uint8 MessageId;

	MessageId = GET_UINT8(pBuffer, 0);
	LLOGLN(10, ("audin_on_data_received: MessageId=0x%x", MessageId));
	switch (MessageId)
	{
		case MSG_SNDIN_VERSION:
			audin_process_version(pChannelCallback, pBuffer + 1, cbSize - 1);
			break;
		case MSG_SNDIN_FORMATS:
			audin_process_formats(pChannelCallback, pBuffer + 1, cbSize - 1);
			break;
		case MSG_SNDIN_OPEN:
			audin_process_open(pChannelCallback, pBuffer + 1, cbSize - 1);
			break;
		case MSG_SNDIN_FORMATCHANGE:
			audin_process_format_change(pChannelCallback, pBuffer + 1, cbSize - 1);
			break;
		default:
			LLOGLN(0, ("audin_on_data_received: unknown MessageId=0x%x", MessageId));
			break;
	}
	return 0;
}
Esempio n. 2
0
static int
thread_process_message_wave_info(rdpsndPlugin * plugin, char * data, int data_size)
{
	int wFormatNo;
	int error;

	if (plugin->device_plugin)
		error = plugin->device_plugin->open(plugin->device_plugin);
	else
		error = 1;

	plugin->wTimeStamp = GET_UINT16(data, 0); /* time in ms */
	plugin->local_time_stamp = get_mstime(); /* time in ms */
	wFormatNo = GET_UINT16(data, 2);
	LLOGLN(10, ("thread_process_message_wave_info: data_size %d "
		"wFormatNo %d", data_size, wFormatNo));
	plugin->cBlockNo = GET_UINT8(data, 4);
	plugin->waveDataSize = data_size - 8;
	memcpy(plugin->waveData, data + 8, 4);
	if (wFormatNo != plugin->current_format && !error)
	{
		plugin->current_format = wFormatNo;
		set_format(plugin);
	}
	plugin->expectingWave = 1;
	return error;
}
Esempio n. 3
0
void
irp_process_notify_change_directory_request(IRP* irp, char* data, int data_size)
{
	irp->watchTree = GET_UINT8(data, 0); /* watchQuery */
	irp->completionFilter = GET_UINT32(data, 1); /* completionQuery */
	/* 27-byte pad */

	if (!irp->dev->service->notify_change_directory)
	{
		irp->ioStatus = RD_STATUS_NOT_SUPPORTED;
	}
	else
	{
		irp->ioStatus = irp->dev->service->notify_change_directory(irp);
	}
}
Esempio n. 4
0
static int
thread_process_message(rdpsndPlugin * plugin, char * data, int data_size)
{
	int opcode;
	int size;
	static int wave_error = 0;

	if (plugin->expectingWave)
	{
		if (!wave_error)
			thread_process_message_wave(plugin, data, data_size);
		plugin->expectingWave = 0;
		return 0;
	}
	opcode = GET_UINT8(data, 0);
	size = GET_UINT16(data, 2);
	LLOGLN(10, ("thread_process_message: data_size %d opcode %d size %d",
		data_size, opcode, size));
	switch (opcode)
	{
		case SNDC_FORMATS:
			thread_process_message_formats(plugin, data + 4, size);
			break;
		case SNDC_TRAINING:
			thread_process_message_training(plugin, data + 4, size);
			break;
		case SNDC_WAVE:
			if (!wave_error)
				wave_error = thread_process_message_wave_info(plugin, data + 4, size);
			break;
		case SNDC_CLOSE:
			thread_process_message_close(plugin, data + 4, size);
			wave_error = 0;
			break;
		case SNDC_SETVOLUME:
			thread_process_message_setvolume(plugin, data + 4, size);
			break;
		case 0: /* wave PDU: ignoring it since it is received only if wave_error == 1*/
			break;
		default:
			LLOGLN(0, ("thread_process_message: unknown opcode"));
			break;
	}
	return 0;
}
Esempio n. 5
0
static int
thread_process_message(drdynvcPlugin * plugin, char * data, int data_size)
{
	int value;
	int Cmd;
	int Sp;
	int cbChId;
	int rv;

	rv = 0;
	value = GET_UINT8(data, 0);
	Cmd = (value & 0xf0) >> 4;
	Sp = (value & 0x0c) >> 2;
	cbChId = (value & 0x03) >> 0;
	LLOGLN(10, ("thread_process_message: data_size %d cmd 0x%x", data_size, Cmd));
	hexdump(data, data_size);
	switch (Cmd)
	{
		case CAPABILITY_REQUEST_PDU:
			rv = process_CAPABILITY_REQUEST_PDU(plugin, Sp, cbChId, data, data_size);
			break;
		case CREATE_REQUEST_PDU:
			rv = process_CREATE_REQUEST_PDU(plugin, Sp, cbChId, data, data_size);
			break;
		case DATA_FIRST_PDU:
			rv = process_DATA_FIRST_PDU(plugin, Sp, cbChId, data, data_size);
			break;
		case DATA_PDU:
			rv = process_DATA_PDU(plugin, Sp, cbChId, data, data_size);
			break;
		case CLOSE_REQUEST_PDU:
			rv = process_CLOSE_REQUEST_PDU(plugin, Sp, cbChId, data, data_size);
			break;
		default:
			LLOGLN(0, ("thread_process_message: unknown drdynvc cmd 0x%x", Cmd));
			break;
	}
	return rv;
}
Esempio n. 6
0
static uint32
get_variable_uint(int cbLen, char * data, int * pos)
{
	uint32 val;

	switch (cbLen)
	{
		case 0:
			val = (uint32) GET_UINT8(data, *pos);
			*pos += 1;
			break;
		case 1:
			val = (uint32) GET_UINT16(data, *pos);
			*pos += 2;
			break;
		default:
			val = (uint32) GET_UINT32(data, *pos);
			*pos += 4;
			break;
	}
	return val;
}
Esempio n. 7
0
void
irp_process_query_directory_request(IRP* irp, char* data, int data_size)
{
	UNICONV * uniconv;
	uint8 initialQuery;
	uint32 pathLength;
	char * path;

	irp->infoClass = GET_UINT32(data, 0); /* fsInformationClass */
	initialQuery = GET_UINT8(data, 4); /* initialQuery */
	pathLength = GET_UINT32(data, 5); /* pathLength */
	/* 23-byte pad */

	uniconv = freerdp_uniconv_new();
	path = freerdp_uniconv_in(uniconv, (unsigned char*) (&data[32]), pathLength);
	freerdp_uniconv_free(uniconv);

	if (!irp->dev->service->query_directory)
	{
		irp->ioStatus = RD_STATUS_NOT_SUPPORTED;
	}
	else
	{
		irp->ioStatus = irp->dev->service->query_directory(irp, initialQuery, path);
	}
	free(path);

	if (irp->ioStatus == RD_STATUS_NO_MORE_FILES)
	{
		/* [MS-RDPEFS] said it's an optional padding, however it's *required* for this last query!!! */
		irp->outputBufferLength = 1;
		irp->outputBuffer = malloc(1);
		irp->outputBuffer[0] = '\0';
	}
	else
	{
		irp->outputResult = irp->outputBufferLength;
	}
}
Esempio n. 8
0
void
irp_process_file_lock_control_request(IRP* irp, char* data, int data_size)
{
	uint32 numLocks;

	irp->operation = GET_UINT32(data, 0); /* operation */
	irp->waitOperation = GET_UINT8(data, 4); /* f (first bit) */
	/* pad (f + pad = 32 bits) */
	numLocks = GET_UINT32(data, 8); /* numLocks */
	irp->inputBufferLength = numLocks * 16; /* sizeof(RDP_LOCK_INFO) */
	/* 20-byte pad */
	irp->inputBuffer = data + 32;

	if (!irp->dev->service->lock_control)
	{
		irp->ioStatus = RD_STATUS_NOT_SUPPORTED;
	}
	else
	{
		irp->ioStatus = irp->dev->service->lock_control(irp);
		irp->outputResult = irp->outputBufferLength;
	}
}
Esempio n. 9
0
int s3g_command_read_ext(s3g_context_t *ctx, s3g_command_t *cmd,
			 unsigned char *buf, size_t maxbuf, size_t *buflen)
{
     unsigned char *buf0 = buf;
     ssize_t bytes_expected, bytes_read;
     s3g_command_info_t *ct;
     s3g_command_t dummy;
     foo_32_t f32;
     int iret;
     uint8_t ui8arg;

     iret = -1;

     if (buflen)
	  *buflen = 0;

     // We have to have a read context
     // We don't need a command context to return the command in
     if (!ctx || !buf || maxbuf == 0)
     {
	  fprintf(stderr, "s3g_command_get(%d): Invalid call; ctx=%p, buf=%p, "
		  "maxbuf=%u\n", __LINE__, (void *)ctx, (void *)buf, maxbuf);
	  errno = EINVAL;
	  return(-1);
     }
     else if (!ctx->read)
     {
	  fprintf(stderr, "s3g_command_get(%d): Invalid context; "
		  "ctx->read=NULL\n", __LINE__);
	  errno = EINVAL;
	  return(-1);
     }
     else if (!buf || maxbuf == 0)
     {
	  fprintf(stderr, "s3g_command_get(%d): Invalid context; "
		  "ctx->read=NULL\n", __LINE__);
	  errno = EINVAL;
	  return(-1);
     }

     // Initialize command table
     s3g_init();

     if (1 != (bytes_expected = (*ctx->read)(ctx->rw_ctx, buf, maxbuf, 1)))
     {
	  // End of file condition?
	  if (bytes_expected == 0)
	       return(1); // EOF

	  fprintf(stderr,
		  "s3g_command_get(%d): Error while reading from the s3g file; "
		  "%s (%d)\n",
		  __LINE__, strerror(errno), errno);
	  return(-1);
     }

     ct = command_table + buf[0];  // &command_table[buf[0]]

     buf    += 1;
     maxbuf -= 1;

     if (!cmd)
	  cmd = &dummy;

     cmd->cmd_id   = ct->cmd_id;
     cmd->cmd_name = ct->cmd_name;
     cmd->cmd_len  = ct->cmd_len;

     if (ct->cmd_name == NULL)
     {
	  fprintf(stderr,
		  "s3g_command_get(%d): Unrecognized command, %d\n",
		  __LINE__, buf[0]);
	  goto done;
     }

     switch(cmd->cmd_id)
     {
     default :
     case HOST_CMD_CHANGE_TOOL :
     case HOST_CMD_ENABLE_AXES :
     case HOST_CMD_SET_POSITION :
     case HOST_CMD_DELAY :
     case HOST_CMD_FIND_AXES_MINIMUM :
     case HOST_CMD_FIND_AXES_MAXIMUM :
     case HOST_CMD_WAIT_FOR_TOOL :
     case HOST_CMD_WAIT_FOR_PLATFORM :
     case HOST_CMD_STORE_HOME_POSITION :
     case HOST_CMD_RECALL_HOME_POSITION :
     case HOST_CMD_SET_MAX_ACCEL :
     case HOST_CMD_SET_MAX_FEEDRATE :
     case HOST_CMD_SET_DEFAULT_ACCEL :
     case HOST_CMD_SET_ADVANCED_ACCEL :
     case HOST_CMD_SET_ADVANCED_ACCEL2 :
     case HOST_CMD_SET_ADVANCE_K :
     case HOST_CMD_SET_EXTRUDER_STEPSMM :
     case HOST_CMD_SET_ACCELERATION :
     case HOST_CMD_MOOD_LIGHT_SET_RGB :
     case HOST_CMD_MOOD_LIGHT_SET_HSB :
     case HOST_CMD_MOOD_LIGHT_PLAY_SCRIPT :
     case HOST_CMD_BUZZER_REPEATS :
     case HOST_CMD_BUZZER_BUZZ :
     case HOST_CMD_SET_AXIS_STEPS_MM :
	  // Just read the data
	  bytes_expected = (ssize_t)(ct->cmd_len & 0x7fffffff);
	  if ((bytes_read = (*ctx->read)(ctx->rw_ctx, buf, maxbuf,
					 ct->cmd_len)) != bytes_expected)
	       goto io_error;

	  buf    += bytes_read;
	  maxbuf -= bytes_read;
	  break;

#define GET_INT32(v) \
	  if (maxbuf < 4) goto trunc; \
	  if (4 != (bytes_read = (*ctx->read)(ctx->rw_ctx, buf, maxbuf, 4))) \
	       goto io_error; \
	  memcpy(&f32.u.c, buf, 4); \
	  buf    += bytes_read; \
	  maxbuf -= bytes_read; \
	  cmd->t.v = f32.u.i

#define GET_UINT8(v) \
	  if (maxbuf < 1) goto trunc; \
	  if (1 != (bytes_read = (*ctx->read)(ctx->rw_ctx, buf, maxbuf, 1))) \
	       goto io_error; \
	  ui8arg = buf[0]; \
	  buf    += bytes_read; \
	  maxbuf -= bytes_read; \
	  cmd->t.v = ui8arg

#define ZERO(v,c) cmd->t.v = (c)0

     case HOST_CMD_TOOL_COMMAND :
	  // This command is VERY MBI specific
	  if ((ssize_t)3 != (*ctx->read)(ctx->rw_ctx, buf, maxbuf, 3))
	       goto io_error;
	  if (cmd)
	       cmd->cmd_len = (size_t)buf[2];
	  cmd->t.tool.subcmd_id  = buf[1];
	  cmd->t.tool.index      = buf[0];
	  cmd->t.tool.subcmd_len = bytes_expected = (ssize_t)buf[2];
	  if ((bytes_read = (*ctx->read)(ctx->rw_ctx, buf + 3, maxbuf - 3,
					 (size_t)buf[2])) != bytes_expected)
	       goto io_error;

	  if (cmd->t.tool.subcmd_len == 1)
	       cmd->t.tool.subcmd_value = (uint16_t)buf[3];
	  else if (cmd->t.tool.subcmd_len > 1)
	       memcpy((void *)&cmd->t.tool.subcmd_value, buf + 3, sizeof(uint16_t));
	  else
	       cmd->t.tool.subcmd_value = 0;

	  maxbuf -= 3 + bytes_read;
	  buf    += 3 + bytes_read;

	  switch (cmd->t.tool.subcmd_id)
	  {
	  case SLAVE_CMD_SET_TEMP :
	       cmd->t.tool.subcmd_name = "set temperature";
	       break;

	  case SLAVE_CMD_SET_PLATFORM_TEMP :
	       cmd->t.tool.subcmd_name = "set platform temperature";
	       break;

	  case SLAVE_CMD_SET_MOTOR_1_PWM :
	       cmd->t.tool.subcmd_name = "set motor 1 PWM";
	       break;

	  case SLAVE_CMD_TOGGLE_MOTOR_1 :
	       cmd->t.tool.subcmd_name = "toggle motor 1";
	       break;

	  case SLAVE_CMD_TOGGLE_ABP :
	       cmd->t.tool.subcmd_name = "toggle ABP";
	       break;

	  case SLAVE_CMD_TOGGLE_VALVE :
	       if (cmd->t.tool.subcmd_value == 0)
		    cmd->t.tool.subcmd_name = "segment acceleration off";
	       else
		    cmd->t.tool.subcmd_name = "segment acceleration on";
	       break;

	  default :
	       cmd->t.tool.subcmd_name = "unknown subcommand";
	       break;
	  }
	  break;

     case HOST_CMD_SET_POSITION_EXT :
	  // x4, y4, z4, a4, b4 = 20 bytes
	  GET_INT32(set_position_ext.x);
	  GET_INT32(set_position_ext.y);
	  GET_INT32(set_position_ext.z);
	  GET_INT32(set_position_ext.a);
	  GET_INT32(set_position_ext.b);
	  break;

     case HOST_CMD_QUEUE_POINT_EXT :
	  // x4, y4, z4, a4, b4, dda4 = 24 bytes
	  GET_INT32(queue_point_ext.x);
	  GET_INT32(queue_point_ext.y);
	  GET_INT32(queue_point_ext.z);
	  GET_INT32(queue_point_ext.a);
	  GET_INT32(queue_point_ext.b);
	  GET_INT32(queue_point_ext.dda);
	  ZERO(queue_point_ext.dummy_rel, uint8_t);
	  break;

     case HOST_CMD_QUEUE_POINT_NEW :
	  // x4, y4, z4, a4, b4, us4, relative = 25 bytes
	  GET_INT32(queue_point_new.x);
	  GET_INT32(queue_point_new.y);
	  GET_INT32(queue_point_new.z);
	  GET_INT32(queue_point_new.a);
	  GET_INT32(queue_point_new.b);
	  GET_INT32(queue_point_new.us);
	  GET_UINT8(queue_point_new.rel);
	  break;

     case HOST_CMD_QUEUE_POINT_ABS :
	  // x4, y4, z4, dda4 = 16 bytes
	  GET_INT32(queue_point_abs.x);
	  GET_INT32(queue_point_abs.y);
	  GET_INT32(queue_point_abs.z);
	  GET_INT32(queue_point_abs.dda);
	  ZERO(queue_point_abs.dummy_a, int32_t);
	  ZERO(queue_point_abs.dummy_b, int32_t);
	  ZERO(queue_point_abs.dummy_rel, uint8_t);
	  break;
     }

#undef ZERO
#undef GET_UINT8
#undef GET_INT32

     iret = 0;
     goto done;

io_error:
     fprintf(stderr,
	     "s3g_command_get(%d): Error while reading from the s3g file; "
	     "%s (%d)\n",
	     __LINE__, strerror(errno), errno);
     iret = -1;
     goto done;

trunc:
     fprintf(stderr,
	     "s3g_command_get(%d): Caller supplied read buffer is too small",
	     __LINE__);
     iret = -1;

done:
     if (buflen)
	  *buflen = (size_t)(buf - buf0);

     return(iret);
}
Esempio n. 10
0
static uint32
serial_control(IRP * irp)
{
	int flush_mask, purge_mask;
	uint32 result, modemstate;
	uint8 immediate;
	int size = 0, ret = RD_STATUS_SUCCESS;
	SERIAL_DEVICE_INFO *info = (SERIAL_DEVICE_INFO *) irp->dev->info;
	char *inbuf = irp->inputBuffer;
	char *outbuf = NULL;

	/* the server commands, we obbey */
	switch (irp->ioControlCode)
	{
		case IOCTL_SERIAL_SET_BAUD_RATE:
			info->baud_rate = GET_UINT32(inbuf, 0);
			set_termios(info);
			LLOGLN(10, ("serial_ioctl -> SERIAL_SET_BAUD_RATE %d", info->baud_rate));
			break;
		case IOCTL_SERIAL_GET_BAUD_RATE:
			size = 4;
			outbuf = malloc(size);
			SET_UINT32(outbuf, 0, info->baud_rate);
			LLOGLN(10, ("serial_ioctl -> SERIAL_GET_BAUD_RATE %d", info->baud_rate));
			break;
		case IOCTL_SERIAL_SET_QUEUE_SIZE:
			info->queue_in_size = GET_UINT32(inbuf, 0);
			info->queue_out_size = GET_UINT32(inbuf, 4);
			LLOGLN(10, ("serial_ioctl -> SERIAL_SET_QUEUE_SIZE in %d out %d", info->queue_in_size, info->queue_out_size));
			break;
		case IOCTL_SERIAL_SET_LINE_CONTROL:
			info->stop_bits = GET_UINT8(inbuf, 0);
			info->parity = GET_UINT8(inbuf, 1);
			info->word_length = GET_UINT8(inbuf, 2);
			set_termios(info);
			LLOGLN(10, ("serial_ioctl -> SERIAL_SET_LINE_CONTROL stop %d parity %d word %d",
					info->stop_bits, info->parity, info->word_length));
			break;
		case IOCTL_SERIAL_GET_LINE_CONTROL:
			LLOGLN(10, ("serial_ioctl -> SERIAL_GET_LINE_CONTROL"));
			size = 3;
			outbuf = malloc(size);
			SET_UINT8(outbuf, 0, info->stop_bits);
			SET_UINT8(outbuf, 1, info->parity);
			SET_UINT8(outbuf, 2, info->word_length);
			break;
		case IOCTL_SERIAL_IMMEDIATE_CHAR:
			LLOGLN(10, ("serial_ioctl -> SERIAL_IMMEDIATE_CHAR"));
			immediate = GET_UINT8(inbuf, 0);
			serial_write_data(irp, &immediate, 1);
			break;
		case IOCTL_SERIAL_CONFIG_SIZE:
			LLOGLN(10, ("serial_ioctl -> SERIAL_CONFIG_SIZE"));
			size = 4;
			outbuf = malloc(size);
			SET_UINT32(outbuf, 0, 0);
			break;
		case IOCTL_SERIAL_GET_CHARS:
			LLOGLN(10, ("serial_ioctl -> SERIAL_GET_CHARS"));
			size = 6;
			outbuf = malloc(size);
			memcpy(outbuf, info->chars, size);
			break;
		case IOCTL_SERIAL_SET_CHARS:
			LLOGLN(10, ("serial_ioctl -> SERIAL_SET_CHARS"));
			memcpy(info->chars, inbuf, 6);
			set_termios(info);
			break;
		case IOCTL_SERIAL_GET_HANDFLOW:
			LLOGLN(10, ("serial_ioctl -> IOCTL_SERIAL_GET_HANDFLOW"));
			size = 16;
			outbuf = malloc(size);
			get_termios(info);
			SET_UINT32(outbuf, 0, info->control);
			SET_UINT32(outbuf, 4, info->xonoff);
			SET_UINT32(outbuf, 8, info->onlimit);
			SET_UINT32(outbuf, 12, info->offlimit);
			break;
		case IOCTL_SERIAL_SET_HANDFLOW:
			info->control = GET_UINT32(inbuf, 0);
			info->xonoff = GET_UINT32(inbuf, 4);
			info->onlimit = GET_UINT32(inbuf, 8);
			info->offlimit = GET_UINT32(inbuf, 12);
			LLOGLN(10, ("serial_ioctl -> IOCTL_SERIAL_SET_HANDFLOW %x %x %x %x",
				      info->control, info->xonoff, info->onlimit, info->onlimit));
			set_termios(info);
			break;
		case IOCTL_SERIAL_SET_TIMEOUTS:
			info->read_interval_timeout = GET_UINT32(inbuf, 0);
			info->read_total_timeout_multiplier = GET_UINT32(inbuf, 4);
			info->read_total_timeout_constant = GET_UINT32(inbuf, 8);
			info->write_total_timeout_multiplier = GET_UINT32(inbuf, 12);
			info->write_total_timeout_constant = GET_UINT32(inbuf, 16);

			/* http://www.codeproject.com/KB/system/chaiyasit_t.aspx, see 'ReadIntervalTimeout' section
				http://msdn.microsoft.com/en-us/library/ms885171.aspx */
			if (info->read_interval_timeout == SERIAL_TIMEOUT_MAX)
			{
				info->read_interval_timeout = 0;
				info->read_total_timeout_multiplier = 0;
			}

			LLOGLN(10, ("serial_ioctl -> SERIAL_SET_TIMEOUTS read timeout %d %d %d",
				      info->read_interval_timeout,
				      info->read_total_timeout_multiplier,
				      info->read_total_timeout_constant));
			break;
		case IOCTL_SERIAL_GET_TIMEOUTS:
			LLOGLN(10, ("serial_ioctl -> SERIAL_GET_TIMEOUTS read timeout %d %d %d",
				      info->read_interval_timeout,
				      info->read_total_timeout_multiplier,
				      info->read_total_timeout_constant));
			size = 20;
			outbuf = malloc(size);
			SET_UINT32(outbuf, 0, info->read_interval_timeout);
			SET_UINT32(outbuf, 4, info->read_total_timeout_multiplier);
			SET_UINT32(outbuf, 8, info->read_total_timeout_constant);
			SET_UINT32(outbuf, 12, info->write_total_timeout_multiplier);
			SET_UINT32(outbuf, 16, info->write_total_timeout_constant);
			break;
		case IOCTL_SERIAL_GET_WAIT_MASK:
			LLOGLN(10, ("serial_ioctl -> SERIAL_GET_WAIT_MASK %X", info->wait_mask));
			size = 4;
			outbuf = malloc(size);
			SET_UINT32(outbuf, 0, info->wait_mask);
			break;
		case IOCTL_SERIAL_SET_WAIT_MASK:
			info->wait_mask = GET_UINT32(inbuf, 0);
			LLOGLN(10, ("serial_ioctl -> SERIAL_SET_WAIT_MASK %X", info->wait_mask));
			break;
		case IOCTL_SERIAL_SET_DTR:
			LLOGLN(10, ("serial_ioctl -> SERIAL_SET_DTR"));
			ioctl(info->file, TIOCMGET, &result);
			result |= TIOCM_DTR;
			ioctl(info->file, TIOCMSET, &result);
			info->dtr = 1;
			break;
		case IOCTL_SERIAL_CLR_DTR:
			LLOGLN(10, ("serial_ioctl -> SERIAL_CLR_DTR"));
			ioctl(info->file, TIOCMGET, &result);
			result &= ~TIOCM_DTR;
			ioctl(info->file, TIOCMSET, &result);
			info->dtr = 0;
			break;
		case IOCTL_SERIAL_SET_RTS:
			LLOGLN(10, ("serial_ioctl -> SERIAL_SET_RTS"));
			ioctl(info->file, TIOCMGET, &result);
			result |= TIOCM_RTS;
			ioctl(info->file, TIOCMSET, &result);
			info->rts = 1;
			break;
		case IOCTL_SERIAL_CLR_RTS:
			LLOGLN(10, ("serial_ioctl -> SERIAL_CLR_RTS"));
			ioctl(info->file, TIOCMGET, &result);
			result &= ~TIOCM_RTS;
			ioctl(info->file, TIOCMSET, &result);
			info->rts = 0;
			break;
		case IOCTL_SERIAL_GET_MODEMSTATUS:
			modemstate = 0;
#ifdef TIOCMGET
			ioctl(info->file, TIOCMGET, &result);
			if (result & TIOCM_CTS)
				modemstate |= SERIAL_MS_CTS;
			if (result & TIOCM_DSR)
				modemstate |= SERIAL_MS_DSR;
			if (result & TIOCM_RNG)
				modemstate |= SERIAL_MS_RNG;
			if (result & TIOCM_CAR)
				modemstate |= SERIAL_MS_CAR;
			if (result & TIOCM_DTR)
				modemstate |= SERIAL_MS_DTR;
			if (result & TIOCM_RTS)
				modemstate |= SERIAL_MS_RTS;
#endif
			LLOGLN(10, ("serial_ioctl -> SERIAL_GET_MODEMSTATUS %X", modemstate));
			size = 4;
			outbuf = malloc(size);
			SET_UINT32(outbuf, 0, modemstate);
			break;
		case IOCTL_SERIAL_GET_COMMSTATUS:
			size = 18;
			outbuf = malloc(size);
			SET_UINT32(outbuf, 0, 0);	/* Errors */
			SET_UINT32(outbuf, 4, 0);	/* Hold reasons */

			result = 0;
#ifdef TIOCINQ
			ioctl(info->file, TIOCINQ, &result);
#endif
			SET_UINT32(outbuf, 8, result);	/* Amount in in queue */
			if (result)
				LLOGLN(10, ("serial_ioctl -> SERIAL_GET_COMMSTATUS in queue %d", result));

			result = 0;
#ifdef TIOCOUTQ
			ioctl(info->file, TIOCOUTQ, &result);
#endif
			SET_UINT32(outbuf, 12, result);	/* Amount in out queue */
			LLOGLN(10, ("serial_ioctl -> SERIAL_GET_COMMSTATUS out queue %d", result));

			SET_UINT8(outbuf, 16, 0);	/* EofReceived */
			SET_UINT8(outbuf, 17, 0);	/* WaitForImmediate */
			break;
		case IOCTL_SERIAL_PURGE:
			purge_mask = GET_UINT32(inbuf, 0);
			LLOGLN(10, ("serial_ioctl -> SERIAL_PURGE purge_mask %X", purge_mask));
			flush_mask = 0;
			if (purge_mask & SERIAL_PURGE_TXCLEAR)
				flush_mask |= TCOFLUSH;
			if (purge_mask & SERIAL_PURGE_RXCLEAR)
				flush_mask |= TCIFLUSH;
			if (flush_mask != 0)
				tcflush(info->file, flush_mask);

			if (purge_mask & SERIAL_PURGE_TXABORT)
				irp->abortIO |= RDPDR_ABORT_IO_WRITE;
			if(purge_mask & SERIAL_PURGE_RXABORT)
				irp->abortIO |= RDPDR_ABORT_IO_READ;
			break;
		case IOCTL_SERIAL_WAIT_ON_MASK:
			LLOGLN(10, ("serial_ioctl -> SERIAL_WAIT_ON_MASK %X", info->wait_mask));
			info->event_pending = 1;
			if (serial_get_event(irp, &result))
			{
				size = 4;
				outbuf = malloc(size);
				LLOGLN(10, ("WAIT end  event = %x", result));
				SET_UINT32(outbuf, 0, result);
				break;
			}
			irp->outputBufferLength = 4;
			ret = RD_STATUS_PENDING;
			break;
		case IOCTL_SERIAL_SET_BREAK_ON:
			LLOGLN(10, ("serial_ioctl -> SERIAL_SET_BREAK_ON"));
			tcsendbreak(info->file, 0);
			break;
		case IOCTL_SERIAL_RESET_DEVICE:
			LLOGLN(10, ("serial_ioctl -> SERIAL_RESET_DEVICE"));
			break;
		case IOCTL_SERIAL_SET_BREAK_OFF:
			LLOGLN(10, ("serial_ioctl -> SERIAL_SET_BREAK_OFF"));
			break;
		case IOCTL_SERIAL_SET_XOFF:
			LLOGLN(10, ("serial_ioctl -> SERIAL_SET_XOFF"));
			break;
		case IOCTL_SERIAL_SET_XON:
			LLOGLN(10, ("serial_ioctl -> SERIAL_SET_XON"));
			tcflow(info->file, TCION);
			break;
		default:
			LLOGLN(10, ("NOT FOUND IoControlCode SERIAL IOCTL %d", irp->ioControlCode));
			return RD_STATUS_INVALID_PARAMETER;
	}

	irp->outputBuffer = outbuf;
	irp->outputBufferLength = size;

	return ret;
}
Esempio n. 11
0
/* called by worker thread
   receives a list of server supported formats and returns a list
   of client supported formats */
static int
thread_process_message_formats(rdpsndPlugin * plugin, char * data, int data_size)
{
	int index;
	int format_count;
	int out_format_count;
	int out_format_size;
	int size;
	int flags;
	int version;
	char * ldata;
	char * out_data;
	char * out_formats;
	char * lout_formats;
	uint32 error;

	/* skip:
		dwFlags (4 bytes),
		dwVolume (4 bytes),
		dwPitch (4 bytes),
		wDGramPort (2 bytes) */
	format_count = GET_UINT16(data, 14); /* wNumberOfFormats */
	if ((format_count < 1) || (format_count > 1000))
	{
		LLOGLN(0, ("thread_process_message_formats: bad format_count %d",
			format_count));
		return 1;
	}
	plugin->cBlockNo = GET_UINT8(data, 16); /* cLastBlockConfirmed */
	version = GET_UINT16(data, 17); /* wVersion */
	if (version < 2)
	{
		LLOGLN(0, ("thread_process_message_formats: warning, old server"));
	}
	LLOGLN(0, ("thread_process_message_formats: version %d", version));
	/* skip:
		bPad (1 byte) */
	/* setup output buffer */
	size = 32 + data_size;
	out_data = (char *) malloc(size);
	out_formats = out_data + 24;
	lout_formats = out_formats;
	/* remainder is sndFormats (variable) */
	ldata = data + 20;
	out_format_count = 0;
	for (index = 0; index < format_count; index++)
	{
		size = 18 + GET_UINT16(ldata, 16);
		if (plugin->device_plugin && plugin->device_plugin->format_supported(plugin->device_plugin, ldata, size))
		{
			memcpy(lout_formats, ldata, size);
			lout_formats += size;
			out_format_count++;
		}
		ldata += size;
	}
	out_format_size = (int) (lout_formats - out_formats);
	if ((out_format_size > 0) && (out_format_count > 0))
	{
		plugin->supported_formats = (char *) malloc(out_format_size);
		memcpy(plugin->supported_formats, out_formats, out_format_size);
		plugin->supported_formats_size = out_format_size;
	}
	else
	{
		LLOGLN(0, ("thread_process_message_formats: error, "
			"no formats supported"));
	}
	size = 24 + out_format_size;
	SET_UINT8(out_data, 0, SNDC_FORMATS); /* Header (4 bytes) */
	SET_UINT8(out_data, 1, 0);
	SET_UINT16(out_data, 2, size - 4);
	flags = TSSNDCAPS_ALIVE | TSSNDCAPS_VOLUME;
	SET_UINT32(out_data, 4, flags); /* dwFlags */
	SET_UINT32(out_data, 8, 0xffffffff); /* dwVolume */
	SET_UINT32(out_data, 12, 0); /* dwPitch */
	SET_UINT16(out_data, 16, 0); /* wDGramPort */
	SET_UINT16(out_data, 18, out_format_count); /* wNumberOfFormats */
	SET_UINT8(out_data, 20, 0); /* cLastBlockConfirmed */
	SET_UINT16(out_data, 21, 2); /* wVersion */
	SET_UINT8(out_data, 23, 0); /* bPad */
	error = plugin->ep.pVirtualChannelWrite(plugin->open_handle,
		out_data, size, out_data);
	if (error != CHANNEL_RC_OK)
	{
		LLOGLN(0, ("thread_process_message_formats: "
			"VirtualChannelWrite "
			"failed %d", error));
		return 1;
	}
	if (version >= 6)
	{
		size = 8;
		out_data = (char *) malloc(size);
		SET_UINT8(out_data, 0, SNDC_QUALITYMODE); /* Header (4 bytes) */
		SET_UINT8(out_data, 1, 0);
		SET_UINT16(out_data, 2, size - 4);
		SET_UINT16(out_data, 4, 2); /* HIGH_QUALITY */
		SET_UINT16(out_data, 6, 0); /* Reserved (2 bytes) */
		error = plugin->ep.pVirtualChannelWrite(plugin->open_handle,
			out_data, size, out_data);
		if (error != CHANNEL_RC_OK)
		{
			LLOGLN(0, ("thread_process_message_formats: "
				"VirtualChannelWrite "
				"failed %d", error));
			return 1;
		}
	}
	return 0;
}
int s3g_command_read_ext(s3g_context_t *ctx, s3g_command_t *cmd,
			 unsigned char *buf, size_t maxbuf, size_t *buflen)
{
     unsigned char *buf0 = buf;
     ssize_t bytes_expected, bytes_read;
     s3g_command_info_t *ct;
     s3g_command_t dummy;
     foo_16_t f16;
     foo_32_t f32;
     int iret;
     uint8_t ui8arg;

     iret = -1;

     if (buflen)
	  *buflen = 0;

     // We have to have a read context
     // We don't need a command context to return the command in
     if (!ctx || !buf || maxbuf == 0)
     {
	  fprintf(stderr, "s3g_command_get(%d): Invalid call; ctx=%p, buf=%p, "
		  "maxbuf=%lu\n", __LINE__, (void *)ctx, (void *)buf, maxbuf);
	  errno = EINVAL;
	  return(-1);
     }
     else if (!ctx->read)
     {
	  fprintf(stderr, "s3g_command_get(%d): Invalid context; "
		  "ctx->read=NULL\n", __LINE__);
	  errno = EINVAL;
	  return(-1);
     }
     else if (!buf || maxbuf == 0)
     {
	  fprintf(stderr, "s3g_command_get(%d): Invalid context; "
		  "ctx->read=NULL\n", __LINE__);
	  errno = EINVAL;
	  return(-1);
     }

     // Initialize command table
     s3g_init();

     if (1 != (bytes_expected = (*ctx->read)(ctx->r_ctx, buf0, maxbuf, 1)))
     {
	  // End of file condition?
	  if (bytes_expected == 0)
	       return(1); // EOF

	  fprintf(stderr,
		  "s3g_command_get(%d): Error while reading from the s3g file; "
		  "%s (%d)\n",
		  __LINE__, strerror(errno), errno);
	  return(-1);
     }

     ct = command_table + buf0[0];  // &command_table[buf0[0]]

     buf    += 1;
     maxbuf -= 1;

     if (!cmd)
	  cmd = &dummy;

     cmd->cmd_id      = ct->cmd_id;
     cmd->cmd_desc    = ct->cmd_desc;
     cmd->cmd_len     = ct->cmd_len;
     cmd->cmd_raw_len = 0;

     if (ct->cmd_desc == NULL)
     {
	  fprintf(stderr,
		  "s3g_command_get(%d): Unrecognized command, %d\n",
		  __LINE__, buf0[0]);
	  goto done;
     }

#define GET_INT32(v) \
	  if (maxbuf < 4) goto trunc; \
	  if (4 != (bytes_read = (*ctx->read)(ctx->r_ctx, buf, maxbuf, 4))) \
	       goto io_error; \
	  memcpy(&f32.u.c, buf, 4); \
	  buf    += bytes_read; \
	  maxbuf -= bytes_read; \
	  cmd->t.v = f32.u.i

#define GET_UINT32(v) \
	  if (maxbuf < 4) goto trunc; \
	  if (4 != (bytes_read = (*ctx->read)(ctx->r_ctx, buf, maxbuf, 4))) \
	       goto io_error; \
	  memcpy(&f32.u.c, buf, 4); \
	  buf    += bytes_read; \
	  maxbuf -= bytes_read; \
	  cmd->t.v = f32.u.u

#define GET_FLOAT32(v) \
	  if (maxbuf < 4) goto trunc; \
	  if (4 != (bytes_read = (*ctx->read)(ctx->r_ctx, buf, maxbuf, 4))) \
	       goto io_error; \
	  memcpy(&f32.u.c, buf, 4); \
	  buf    += bytes_read; \
	  maxbuf -= bytes_read; \
	  cmd->t.v = f32.u.f;

#define GET_UINT8(v) \
	  if (maxbuf < 1) goto trunc; \
	  if (1 != (bytes_read = (*ctx->read)(ctx->r_ctx, buf, maxbuf, 1))) \
	       goto io_error; \
	  ui8arg = buf[0]; \
	  buf    += bytes_read; \
	  maxbuf -= bytes_read; \
	  cmd->t.v = ui8arg

#define GET_INT16(v) \
	  if (maxbuf < 2) goto trunc; \
	  if (2 != (bytes_read = (*ctx->read)(ctx->r_ctx, buf, maxbuf, 2))) \
	       goto io_error; \
	  memcpy(&f16.u.c, buf, 2); \
	  buf    += bytes_read; \
	  maxbuf -= bytes_read; \
	  cmd->t.v = f16.u.i

#define GET_UINT16(v) \
	  if (maxbuf < 2) goto trunc; \
	  if (2 != (bytes_read = (*ctx->read)(ctx->r_ctx, buf, maxbuf, 2))) \
	       goto io_error; \
	  memcpy(&f16.u.c, buf, 2); \
	  buf    += bytes_read; \
	  maxbuf -= bytes_read; \
	  cmd->t.v = f16.u.u

#define ZERO(v,c) cmd->t.v = (c)0

     switch(cmd->cmd_id)
     {
     case HOST_CMD_DELAY :
	  GET_UINT32(delay.millis);
	  break;

     case HOST_CMD_FIND_AXES_MINIMUM :
     case HOST_CMD_FIND_AXES_MAXIMUM :
	  GET_UINT8(find_axes_minmax.flags);
	  GET_UINT32(find_axes_minmax.feedrate);
	  GET_UINT16(find_axes_minmax.timeout);
	  break;

     case HOST_CMD_WAIT_FOR_TOOL :
	  GET_UINT8(wait_for_tool.index);
	  GET_UINT16(wait_for_tool.ping_delay);
	  GET_UINT16(wait_for_tool.timeout);
	  break;

     case HOST_CMD_WAIT_FOR_PLATFORM :
	  GET_UINT8(wait_for_platform.index);
	  GET_UINT16(wait_for_platform.ping_delay);
	  GET_UINT16(wait_for_platform.timeout);
	  break;

     case HOST_CMD_STORE_HOME_POSITION :
	  GET_UINT8(store_home_position.axes);
	  break;

     case HOST_CMD_RECALL_HOME_POSITION :
	  GET_UINT8(recall_home_position.axes);
	  break;

     default :
	  // Just read the data
	  bytes_expected = (ssize_t)(ct->cmd_len & 0x7fffffff);
	  if ((bytes_read = (*ctx->read)(ctx->r_ctx, buf, maxbuf,
					 ct->cmd_len)) != bytes_expected)
	       goto io_error;

	  buf    += bytes_read;
	  maxbuf -= bytes_read;
	  break;

     case HOST_CMD_TOOL_COMMAND :
	  // This command is VERY MBI specific
	  if ((ssize_t)3 != (*ctx->read)(ctx->r_ctx, buf, maxbuf, 3))
	       goto io_error;
	  if (cmd)
	       cmd->cmd_len = (size_t)buf[2];
	  cmd->t.tool.subcmd_id  = buf[1];
	  cmd->t.tool.index      = buf[0];
	  cmd->t.tool.subcmd_len = bytes_expected = (ssize_t)buf[2];
	  if ((bytes_read = (*ctx->read)(ctx->r_ctx, buf + 3, maxbuf - 3,
					 (size_t)buf[2])) != bytes_expected)
	       goto io_error;

	  if (cmd->t.tool.subcmd_len == 1)
	       cmd->t.tool.subcmd_value = (uint16_t)buf[3];
	  else if (cmd->t.tool.subcmd_len > 1)
	       memcpy((void *)&cmd->t.tool.subcmd_value, buf + 3, sizeof(uint16_t));
	  else
	       cmd->t.tool.subcmd_value = 0;

	  maxbuf -= 3 + bytes_read;
	  buf    += 3 + bytes_read;

	  cmd->t.tool.subcmd_desc = tool_command_table[cmd->t.tool.subcmd_id].cmd_desc;
	  if (cmd->t.tool.subcmd_desc == NULL)
	       cmd->t.tool.subcmd_desc = "unknown tool subcommand";
	  break;

     case HOST_CMD_SET_POSITION_EXT :
	  // x4, y4, z4, a4, b4 = 20 bytes
	  GET_INT32(set_position_ext.x);
	  GET_INT32(set_position_ext.y);
	  GET_INT32(set_position_ext.z);
	  GET_INT32(set_position_ext.a);
	  GET_INT32(set_position_ext.b);
	  break;

     case HOST_CMD_QUEUE_POINT_EXT :
	  // x4, y4, z4, a4, b4, dda4 = 24 bytes
	  GET_INT32(queue_point_ext.x);
	  GET_INT32(queue_point_ext.y);
	  GET_INT32(queue_point_ext.z);
	  GET_INT32(queue_point_ext.a);
	  GET_INT32(queue_point_ext.b);
	  GET_INT32(queue_point_ext.dda);
	  ZERO(queue_point_ext.dummy_rel, uint8_t);
	  ZERO(queue_point_ext.dummy_distance, float);
	  ZERO(queue_point_ext.dummy_feedrate_mult_64, uint16_t);
	  break;

     case HOST_CMD_QUEUE_POINT_NEW :
	  // x4, y4, z4, a4, b4, us4, relative = 25 bytes
	  GET_INT32(queue_point_new.x);
	  GET_INT32(queue_point_new.y);
	  GET_INT32(queue_point_new.z);
	  GET_INT32(queue_point_new.a);
	  GET_INT32(queue_point_new.b);
	  GET_INT32(queue_point_new.us);
	  GET_UINT8(queue_point_new.rel);
	  ZERO(queue_point_ext.dummy_distance, float);
	  ZERO(queue_point_ext.dummy_feedrate_mult_64, uint16_t);
	  break;

     case HOST_CMD_QUEUE_POINT_NEW_EXT :
	  // x4, y4, z4, a4, b4, dda_rate4, relative, distance 4, feedrate_mult64 2 = 31 bytes
	  GET_INT32(queue_point_new_ext.x);
	  GET_INT32(queue_point_new_ext.y);
	  GET_INT32(queue_point_new_ext.z);
	  GET_INT32(queue_point_new_ext.a);
	  GET_INT32(queue_point_new_ext.b);
	  GET_INT32(queue_point_new_ext.dda_rate);
	  GET_UINT8(queue_point_new_ext.rel);
	  GET_FLOAT32(queue_point_new_ext.distance);
	  GET_INT16(queue_point_new_ext.feedrate_mult_64);
	  break;

     case HOST_CMD_SET_POT_VALUE :
	  GET_UINT8(digi_pot.axis);
	  GET_UINT8(digi_pot.value);
	  break;

     case HOST_CMD_SET_RGB_LED :
	  GET_UINT8(rgb_led.red);
	  GET_UINT8(rgb_led.green);
	  GET_UINT8(rgb_led.blue);
	  GET_UINT8(rgb_led.blink_rate);
	  GET_UINT8(rgb_led.effect);
	  break;

     case HOST_CMD_SET_BEEP :
	  GET_UINT16(beep.frequency);
	  GET_UINT16(beep.duration);
	  GET_UINT8(beep.effect);
	  break;

     case HOST_CMD_PAUSE_FOR_BUTTON :
	  GET_UINT8(button_pause.mask);
	  GET_UINT16(button_pause.timeout);
	  GET_UINT8(button_pause.timeout_behavior);
	  break;

     case HOST_CMD_DISPLAY_MESSAGE :
	  GET_UINT8(display_message.options);
	  GET_UINT8(display_message.x);
	  GET_UINT8(display_message.y);
	  GET_UINT8(display_message.timeout);
	  cmd->t.display_message.message_len = 0;
	  if (maxbuf < 1) goto trunc;
	  for (;;)
	  {
	       unsigned char uc;
	       if (1 != (bytes_read = (*ctx->read)(ctx->r_ctx, buf, maxbuf, 1)))
		    goto io_error;
	       uc = buf[0];
	       ++buf;
	       --maxbuf;
	       if (uc == '\0')
		    break;
	       if (cmd->t.display_message.message_len < (sizeof(cmd->t.display_message.message) - 1))
		    cmd->t.display_message.message[cmd->t.display_message.message_len++] = uc;
	       if (maxbuf < 1) goto trunc;
	  }
	  cmd->t.display_message.message[cmd->t.display_message.message_len] = '\0';
	  break;

     case HOST_CMD_SET_BUILD_PERCENT :
	  GET_UINT8(build_percentage.percentage);
	  GET_UINT8(build_percentage.reserved);
	  break;

     case HOST_CMD_QUEUE_SONG :
	  GET_UINT8(queue_song.song_id);
	  break;

     case HOST_CMD_RESET_TO_FACTORY :
	  GET_UINT8(factory_reset.options);
	  break;

     case HOST_CMD_BUILD_START_NOTIFICATION :
	  GET_INT32(build_start.steps);
	  cmd->t.build_start.message_len = 0;
	  if (maxbuf < 1) goto trunc;
	  for (;;)
	  {
	       unsigned char uc;
	       if (1 != (bytes_read = (*ctx->read)(ctx->r_ctx, buf, maxbuf, 1)))
		    goto io_error;
	       uc = buf[0];
	       ++buf;
	       --maxbuf;
	       if (uc == '\0')
		    break;
	       if (cmd->t.build_start.message_len < (sizeof(cmd->t.build_start.message) - 1))
		    cmd->t.build_start.message[cmd->t.build_start.message_len++] = uc;
	  }
	  cmd->t.build_start.message[cmd->t.build_start.message_len] = '\0';
	  break;

     case HOST_CMD_BUILD_END_NOTIFICATION :
	  GET_UINT8(build_end.flags);
	  break;

     case HOST_CMD_CHANGE_TOOL :
	  GET_UINT8(change_tool.index);
          break;

     case HOST_CMD_ENABLE_AXES :
	  GET_UINT8(enable_axes.axes);
          break;

     case HOST_CMD_SET_ACCELERATION_TOGGLE:
	  GET_UINT8(set_segment_acceleration.s);
	  break;

     case HOST_CMD_STREAM_VERSION:
	  GET_UINT8(x3g_version.version_high);
	  GET_UINT8(x3g_version.version_low);
	  GET_UINT8(x3g_version.reserved1);
	  GET_UINT32(x3g_version.reserved2);
	  GET_UINT16(x3g_version.bot_type);
	  GET_UINT16(x3g_version.reserved3);
	  GET_UINT32(x3g_version.reserved4);
	  GET_UINT32(x3g_version.reserved5);
	  GET_UINT8(x3g_version.reserved6);
	  break;
     }

#undef ZERO
#undef GET_UINT8
#undef GET_INT32

     iret = 0;
     goto done;

io_error:
     fprintf(stderr,
	     "s3g_command_get(%d): Error while reading from the s3g file; "
	     "%s (%d)\n",
	     __LINE__, strerror(errno), errno);
     iret = -1;
     goto done;

trunc:
     fprintf(stderr,
	     "s3g_command_get(%d): Caller supplied read buffer is too small",
	     __LINE__);
     iret = -1;

done:
     cmd->cmd_raw_len = (size_t)(buf - buf0);
     if (buflen)
	  *buflen = cmd->cmd_raw_len;

     return(iret);
}