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; }
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; }
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); } }
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; }
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; }
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; }
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; } }
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; } }
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); }
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; }
/* 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); }