int sick_test_baudrate(sick_laser_t* sick, int max_retries){ // printf ("Test baudrate ... "); int baudrates[]={9600, 19200, 38400, 500000}; int baudrates_no=4; unsigned char reply[8192]; int i; sick->baudrate=0; for (i=0; i<baudrates_no; i++){ int j=0; serial_configure(sick->fd, baudrates[i], "8N1"); #ifdef USE_TCP862 tcp862_setBaud(sick->fd,baudrates[i]); #endif fprintf (stderr, "%d ", baudrates[i]); while(j<max_retries){ j++; fprintf(stderr,"."); //FIXME int response=sick_send_packet_noack(sick, reply, cmd_stop_continuous_mode, cmd_stop_continuous_mode_size); if (! response){ continue; } usleep(10000); // fprintf(stderr, "c"); response=sick_send_packet(sick, reply, cmd_stop_continuous_mode, cmd_stop_continuous_mode_size); if (response){ sick->baudrate=baudrates[i]; fprintf(stderr," success\n"); return baudrates[i]; } } fprintf(stderr," failed\n "); } return -1; }
dc_status_t shearwater_common_open (shearwater_common_device_t *device, dc_context_t *context, const char *name) { // Open the device. int rc = serial_open (&device->port, context, name); if (rc == -1) { ERROR (context, "Failed to open the serial port."); return DC_STATUS_IO; } // Set the serial communication protocol (115200 8N1). rc = serial_configure (device->port, 115200, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); if (rc == -1) { ERROR (context, "Failed to set the terminal attributes."); serial_close (device->port); return DC_STATUS_IO; } // Set the timeout for receiving data (3000ms). if (serial_set_timeout (device->port, 3000) == -1) { ERROR (context, "Failed to set the timeout."); serial_close (device->port); return DC_STATUS_IO; } // Make sure everything is in a sane state. serial_sleep (device->port, 300); serial_flush (device->port, SERIAL_QUEUE_BOTH); return DC_STATUS_SUCCESS; }
dc_status_t shearwater_common_custom_open (shearwater_common_device_t *device, dc_context_t *context, dc_serial_t *serial) { // Set the serial reference device->serial = serial; if (serial->type == DC_TRANSPORT_SERIAL) { // Set the serial communication protocol (115200 8N1). int rc = serial_configure (device->serial->port, 115200, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); if (rc == -1) { ERROR (context, "Failed to set the terminal attributes."); device->serial->ops->close (device->serial->port); return DC_STATUS_IO; } } // Set the timeout for receiving data (3000ms). if (device->serial->ops->set_timeout (device->serial->port, 3000) == -1) { ERROR (context, "Failed to set the timeout."); device->serial->ops->close (device->serial->port); return DC_STATUS_IO; } // Make sure everything is in a sane state. serial_sleep (device->serial->port, 300); device->serial->ops->flush (device->serial->port, SERIAL_QUEUE_BOTH); return DC_STATUS_SUCCESS; }
dc_status_t uwatec_meridian_device_open (dc_device_t **out, dc_context_t *context, const char *name) { if (out == NULL) return DC_STATUS_INVALIDARGS; // Allocate memory. uwatec_meridian_device_t *device = (uwatec_meridian_device_t *) malloc (sizeof (uwatec_meridian_device_t)); if (device == NULL) { ERROR (context, "Failed to allocate memory."); return DC_STATUS_NOMEMORY; } // Initialize the base class. device_init (&device->base, context, &uwatec_meridian_device_vtable); // Set the default values. device->port = NULL; device->timestamp = 0; device->systime = (dc_ticks_t) -1; device->devtime = 0; // Open the device. int rc = serial_open (&device->port, context, name); if (rc == -1) { ERROR (context, "Failed to open the serial port."); free (device); return DC_STATUS_IO; } // Set the serial communication protocol (57600 8N1). rc = serial_configure (device->port, 57600, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); if (rc == -1) { ERROR (context, "Failed to set the terminal attributes."); serial_close (device->port); free (device); return DC_STATUS_IO; } // Set the timeout for receiving data (3000ms). if (serial_set_timeout (device->port, 3000) == -1) { ERROR (context, "Failed to set the timeout."); serial_close (device->port); free (device); return DC_STATUS_IO; } // Make sure everything is in a sane state. serial_flush (device->port, SERIAL_QUEUE_BOTH); // Perform the handshaking. uwatec_meridian_handshake (device); *out = (dc_device_t*) device; return DC_STATUS_SUCCESS; }
dc_status_t cressi_leonardo_device_open (dc_device_t **out, dc_context_t *context, const char *name) { if (out == NULL) return DC_STATUS_INVALIDARGS; // Allocate memory. cressi_leonardo_device_t *device = (cressi_leonardo_device_t *) malloc (sizeof (cressi_leonardo_device_t)); if (device == NULL) { ERROR (context, "Failed to allocate memory."); return DC_STATUS_NOMEMORY; } // Initialize the base class. device_init (&device->base, context, &cressi_leonardo_device_vtable); // Set the default values. device->port = NULL; // Open the device. int rc = serial_open (&device->port, context, name); if (rc == -1) { ERROR (context, "Failed to open the serial port."); free (device); return DC_STATUS_IO; } // Set the serial communication protocol (115200 8N1). rc = serial_configure (device->port, 115200, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); if (rc == -1) { ERROR (context, "Failed to set the terminal attributes."); serial_close (device->port); free (device); return DC_STATUS_IO; } // Set the timeout for receiving data (1000 ms). if (serial_set_timeout (device->port, 1000) == -1) { ERROR (context, "Failed to set the timeout."); serial_close (device->port); free (device); return DC_STATUS_IO; } // Clear the DTR and set the RTS line. if (serial_set_dtr (device->port, 0) == -1 || serial_set_rts (device->port, 1) == -1) { ERROR (context, "Failed to set the DTR/RTS line."); serial_close (device->port); free (device); return DC_STATUS_IO; } *out = (dc_device_t *) device; return DC_STATUS_SUCCESS; }
static void serial_reconfig(void *handle, Conf *conf) { Serial serial = (Serial) handle; /* * FIXME: what should we do if this returns an error? */ serial_configure(serial, conf); }
void setup_movement(void) { serial_configure(9600); set_PWM(LEF1, 0); set_PWM(LEF0, 0); set_PWM(RIG0, 0); set_PWM(RIG1, 0); start_encoder(); }
device_status_t suunto_eon_device_open (device_t **out, const char* name) { if (out == NULL) return DEVICE_STATUS_ERROR; // Allocate memory. suunto_eon_device_t *device = (suunto_eon_device_t *) malloc (sizeof (suunto_eon_device_t)); if (device == NULL) { WARNING ("Failed to allocate memory."); return DEVICE_STATUS_MEMORY; } // Initialize the base class. suunto_common_device_init (&device->base, &suunto_eon_device_backend); // Set the default values. device->port = NULL; // Open the device. int rc = serial_open (&device->port, name); if (rc == -1) { WARNING ("Failed to open the serial port."); free (device); return DEVICE_STATUS_IO; } // Set the serial communication protocol (1200 8N2). rc = serial_configure (device->port, 1200, 8, SERIAL_PARITY_NONE, 2, SERIAL_FLOWCONTROL_NONE); if (rc == -1) { WARNING ("Failed to set the terminal attributes."); serial_close (device->port); free (device); return DEVICE_STATUS_IO; } // Set the timeout for receiving data (1000ms). if (serial_set_timeout (device->port, -1) == -1) { WARNING ("Failed to set the timeout."); serial_close (device->port); free (device); return DEVICE_STATUS_IO; } // Clear the RTS line. if (serial_set_rts (device->port, 0)) { WARNING ("Failed to set the DTR/RTS line."); serial_close (device->port); free (device); return DEVICE_STATUS_IO; } *out = (device_t*) device; return DEVICE_STATUS_SUCCESS; }
static void serial_reconfig(void *handle, Config *cfg) { Serial serial = (Serial) handle; const char *err; err = serial_configure(serial, serial->port, cfg); /* * FIXME: what should we do if err returns something? */ }
static void serial_reconfig(Backend *be, Conf *conf) { Serial *serial = container_of(be, Serial, backend); serial_configure(serial, serial->port, conf); /* * FIXME: what should we do if that call returned a non-NULL error * message? */ }
dc_status_t hw_ostc_device_open (dc_device_t **out, dc_context_t *context, const char *name) { if (out == NULL) return DC_STATUS_INVALIDARGS; // Allocate memory. hw_ostc_device_t *device = (hw_ostc_device_t *) malloc (sizeof (hw_ostc_device_t)); if (device == NULL) { ERROR (context, "Failed to allocate memory."); return DC_STATUS_NOMEMORY; } // Initialize the base class. device_init (&device->base, context, &hw_ostc_device_vtable); // Set the default values. device->port = NULL; memset (device->fingerprint, 0, sizeof (device->fingerprint)); // Open the device. int rc = serial_open (&device->port, context, name); if (rc == -1) { ERROR (context, "Failed to open the serial port."); free (device); return DC_STATUS_IO; } // Set the serial communication protocol (115200 8N1). rc = serial_configure (device->port, 115200, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); if (rc == -1) { ERROR (context, "Failed to set the terminal attributes."); serial_close (device->port); free (device); return DC_STATUS_IO; } // Set the timeout for receiving data. if (serial_set_timeout (device->port, 4000) == -1) { ERROR (context, "Failed to set the timeout."); serial_close (device->port); free (device); return DC_STATUS_IO; } // Make sure everything is in a sane state. serial_sleep (device->port, 100); serial_flush (device->port, SERIAL_QUEUE_BOTH); *out = (dc_device_t*) device; return DC_STATUS_SUCCESS; }
int sick_set_baudrate(sick_laser_t* sick, int max_retries, int brate){ unsigned char command[2]; unsigned char reply[1024]; int j=0; int currentbrate=sick->baudrate; int max_response_retries=5; command[0]=0x20; if(brate == 500000) command[1] = 0x48; else if(brate == 38400) command[1] = 0x40; else if(brate == 19200) command[1] = 0x41; else command[1] = 0x42; serial_configure(sick->fd, currentbrate, "8N1"); while(j<max_retries){ sick_send_packet_noanswer(sick, command, 2); //sick_send_packet_noack(sick, reply, command, 2); serial_configure(sick->fd, currentbrate, "8N1"); //serial_ClearInputBuffer(sick->fd); int response=0; int response_retries=0; while(! response && response_retries< max_response_retries){ response=sick_send_packet_noack(sick, reply, cmd_request_status, cmd_request_status_size); response_retries+=(!response); usleep(1); // fprintf(stderr, " %d", response_retries); } if (response){ return response; } j++; } return 0; }
/* * Called to set up the serial connection. * * Returns an error message, or NULL on success. * * Also places the canonical host name into `realhost'. It must be * freed by the caller. */ static const char *serial_init(void *frontend_handle, void **backend_handle, Conf *conf, const char *host, int port, char **realhost, int nodelay, int keepalive) { Serial serial; const char *err; char *line; serial = snew(struct serial_backend_data); *backend_handle = serial; serial->frontend = frontend_handle; serial->finished = FALSE; serial->inbufsize = 0; bufchain_init(&serial->output_data); line = conf_get_str(conf, CONF_serline); { char *msg = dupprintf("Opening serial device %s", line); logevent(serial->frontend, msg); sfree(msg); } serial->fd = open(line, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK); if (serial->fd < 0) return "Unable to open serial port"; cloexec(serial->fd); err = serial_configure(serial, conf); if (err) return err; *realhost = dupstr(line); if (!serial_by_fd) serial_by_fd = newtree234(serial_compare_by_fd); add234(serial_by_fd, serial); serial_uxsel_setup(serial); /* * Specials are always available. */ update_specials_menu(serial->frontend); return NULL; }
/* * Called to set up the serial connection. * * Returns an error message, or NULL on success. * * Also places the canonical host name into `realhost'. It must be * freed by the caller. */ static const char *serial_init(void *frontend_handle, void **backend_handle, Config *cfg, char *host, int port, char **realhost, int nodelay, int keepalive) { Serial serial; HANDLE serport; const char *err; serial = snew(struct serial_backend_data); serial->port = INVALID_HANDLE_VALUE; serial->out = serial->in = NULL; serial->bufsize = 0; serial->break_in_progress = FALSE; *backend_handle = serial; serial->frontend = frontend_handle; { char *msg = dupprintf("Opening serial device %s", cfg->serline); logevent(serial->frontend, msg); } serport = CreateFile(cfg->serline, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); if (serport == INVALID_HANDLE_VALUE) return "Unable to open serial port"; err = serial_configure(serial, serport, cfg); if (err) return err; serial->port = serport; serial->out = handle_output_new(serport, serial_sentdata, serial, HANDLE_FLAG_OVERLAPPED); serial->in = handle_input_new(serport, serial_gotdata, serial, HANDLE_FLAG_OVERLAPPED | HANDLE_FLAG_IGNOREEOF | HANDLE_FLAG_UNITBUFFER); *realhost = dupstr(cfg->serline); /* * Specials are always available. */ update_specials_menu(serial->frontend); return NULL; }
void uart__init(void) { /* Iniitialise the UART */ printf("Initialising UART driver\n"); if(exynos_serial_init(DEV_ID, uart0base, NULL, &uart_dummy_clk, &serial_device)){ printf("Failed to initialise UART\n"); while(1); } ps_cdev_set_flags(&serial_device, serial_device.flags & ~SERIAL_AUTO_CR); serial_configure(&serial_device, BAUD_RATE, 8, PARITY_NONE, 1); /* Prime semaphores */ read_sem_wait(); write_sem_wait(); }
void pre_init(void) { /* Initialise the UART */ printf("Initialising UART driver\n"); if(exynos_serial_init(DEV_ID, (void *) vaddr, NULL, NULL, &serial_device)){ printf("Failed to initialise UART\n"); while(1); } serial_configure(&serial_device, BAUD_RATE, 8, PARITY_NONE, 1); serial_device.flags &= ~SERIAL_AUTO_CR; /* Prime semaphore */ read_sem_wait(); /* Register for IRQs */ interrupt_acknowledge(); }
/* * Think twice before modifying the code for updating the ostc firmware! * It has been carefully developed and tested with assistance from * Heinrichs-Weikamp, using a special development unit. If you start * experimenting with a normal unit and accidentally screw up, you might * brick the device permanently and turn it into an expensive * paperweight. You have been warned! */ dc_status_t hw_ostc_device_fwupdate (dc_device_t *abstract, const char *filename) { dc_status_t rc = DC_STATUS_SUCCESS; hw_ostc_device_t *device = (hw_ostc_device_t *) abstract; dc_context_t *context = (abstract ? abstract->context : NULL); if (!ISINSTANCE (abstract)) return DC_STATUS_INVALIDARGS; // Allocate memory for the firmware data. hw_ostc_firmware_t *firmware = (hw_ostc_firmware_t *) malloc (sizeof (hw_ostc_firmware_t)); if (firmware == NULL) { ERROR (context, "Failed to allocate memory."); return DC_STATUS_NOMEMORY; } // Read the hex file. rc = hw_ostc_firmware_readfile (firmware, context, filename); if (rc != DC_STATUS_SUCCESS) { ERROR (context, "Failed to read the firmware file."); free (firmware); return rc; } // Temporary set a relative short timeout. The command to setup the // bootloader needs to be send repeatedly, until the response packet is // received. Thus the time between each two attempts is directly controlled // by the timeout value. serial_set_timeout (device->port, 300); // Setup the bootloader. const unsigned int baudrates[] = {19200, 115200}; for (unsigned int i = 0; i < C_ARRAY_SIZE(baudrates); ++i) { // Adjust the baudrate. if (serial_configure (device->port, baudrates[i], 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE) == -1) { ERROR (abstract->context, "Failed to set the terminal attributes."); free (firmware); return DC_STATUS_IO; } // Try to setup the bootloader. unsigned int maxretries = (i == 0 ? 1 : MAXRETRIES); rc = hw_ostc_firmware_setup (device, maxretries); if (rc == DC_STATUS_SUCCESS) break; } if (rc != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to setup the bootloader."); free (firmware); return rc; } // Increase the timeout again. serial_set_timeout (device->port, 1000); // Enable progress notifications. dc_event_progress_t progress = EVENT_PROGRESS_INITIALIZER; progress.maximum = C_ARRAY_SIZE(firmware->bitmap); device_event_emit (abstract, DC_EVENT_PROGRESS, &progress); for (unsigned int i = 0; i < C_ARRAY_SIZE(firmware->bitmap); ++i) { // Skip empty blocks. if (firmware->bitmap[i] == 0) continue; // Create the packet. unsigned int address = i * SZ_BLOCK; unsigned char packet[4 + SZ_BLOCK + 1] = { (address >> 16) & 0xFF, (address >> 8) & 0xFF, (address ) & 0xFF, SZ_BLOCK }; memcpy (packet + 4, firmware->data + address, SZ_BLOCK); packet[sizeof (packet) - 1] = ~checksum_add_uint8 (packet, 4 + SZ_BLOCK, 0x00) + 1; // Send the packet. rc = hw_ostc_firmware_write (device, packet, sizeof (packet)); if (rc != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to send the packet."); free (firmware); return rc; } // Update and emit a progress event. progress.current = i + 1; device_event_emit (abstract, DC_EVENT_PROGRESS, &progress); } free (firmware); return DC_STATUS_SUCCESS; }
/* * Called to set up the serial connection. * * Returns an error message, or NULL on success. * * Also places the canonical host name into `realhost'. It must be * freed by the caller. */ static const char *serial_init(Seat *seat, Backend **backend_handle, LogContext *logctx, Conf *conf, const char *host, int port, char **realhost, bool nodelay, bool keepalive) { Serial *serial; HANDLE serport; const char *err; char *serline; /* No local authentication phase in this protocol */ seat_set_trust_status(seat, false); serial = snew(Serial); serial->port = INVALID_HANDLE_VALUE; serial->out = serial->in = NULL; serial->bufsize = 0; serial->break_in_progress = false; serial->backend.vt = &serial_backend; *backend_handle = &serial->backend; serial->seat = seat; serial->logctx = logctx; serline = conf_get_str(conf, CONF_serline); logeventf(serial->logctx, "Opening serial device %s", serline); { /* * Munge the string supplied by the user into a Windows filename. * * Windows supports opening a few "legacy" devices (including * COM1-9) by specifying their names verbatim as a filename to * open. (Thus, no files can ever have these names. See * <http://msdn2.microsoft.com/en-us/library/aa365247.aspx> * ("Naming a File") for the complete list of reserved names.) * * However, this doesn't let you get at devices COM10 and above. * For that, you need to specify a filename like "\\.\COM10". * This is also necessary for special serial and serial-like * devices such as \\.\WCEUSBSH001. It also works for the "legacy" * names, so you can do \\.\COM1 (verified as far back as Win95). * See <http://msdn2.microsoft.com/en-us/library/aa363858.aspx> * (CreateFile() docs). * * So, we believe that prepending "\\.\" should always be the * Right Thing. However, just in case someone finds something to * talk to that doesn't exist under there, if the serial line * contains a backslash, we use it verbatim. (This also lets * existing configurations using \\.\ continue working.) */ char *serfilename = dupprintf("%s%s", strchr(serline, '\\') ? "" : "\\\\.\\", serline); serport = CreateFile(serfilename, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); sfree(serfilename); } if (serport == INVALID_HANDLE_VALUE) return "Unable to open serial port"; err = serial_configure(serial, serport, conf); if (err) return err; serial->port = serport; serial->out = handle_output_new(serport, serial_sentdata, serial, HANDLE_FLAG_OVERLAPPED); serial->in = handle_input_new(serport, serial_gotdata, serial, HANDLE_FLAG_OVERLAPPED | HANDLE_FLAG_IGNOREEOF | HANDLE_FLAG_UNITBUFFER); *realhost = dupstr(serline); /* * Specials are always available. */ seat_update_specials_menu(serial->seat); return NULL; }
device_status_t suunto_d9_device_open (device_t **out, const char* name) { if (out == NULL) return DEVICE_STATUS_ERROR; // Allocate memory. suunto_d9_device_t *device = (suunto_d9_device_t *) malloc (sizeof (suunto_d9_device_t)); if (device == NULL) { WARNING ("Failed to allocate memory."); return DEVICE_STATUS_MEMORY; } // Initialize the base class. suunto_common2_device_init (&device->base, &suunto_d9_device_backend); // Set the default values. device->port = NULL; // Open the device. int rc = serial_open (&device->port, name); if (rc == -1) { WARNING ("Failed to open the serial port."); free (device); return DEVICE_STATUS_IO; } // Set the serial communication protocol (9600 8N1). rc = serial_configure (device->port, 9600, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); if (rc == -1) { WARNING ("Failed to set the terminal attributes."); serial_close (device->port); free (device); return DEVICE_STATUS_IO; } // Set the timeout for receiving data (3000 ms). if (serial_set_timeout (device->port, 3000) == -1) { WARNING ("Failed to set the timeout."); serial_close (device->port); free (device); return DEVICE_STATUS_IO; } // Set the DTR line (power supply for the interface). if (serial_set_dtr (device->port, 1) == -1) { WARNING ("Failed to set the DTR line."); serial_close (device->port); free (device); return DEVICE_STATUS_IO; } // Give the interface 100 ms to settle and draw power up. serial_sleep (100); // Make sure everything is in a sane state. serial_flush (device->port, SERIAL_QUEUE_BOTH); *out = (device_t*) device; return DEVICE_STATUS_SUCCESS; }
dc_status_t oceanic_vtpro_device_open (dc_device_t **out, dc_context_t *context, const char *name) { if (out == NULL) return DC_STATUS_INVALIDARGS; // Allocate memory. oceanic_vtpro_device_t *device = (oceanic_vtpro_device_t *) malloc (sizeof (oceanic_vtpro_device_t)); if (device == NULL) { ERROR (context, "Failed to allocate memory."); return DC_STATUS_NOMEMORY; } // Initialize the base class. oceanic_common_device_init (&device->base, context, &oceanic_vtpro_device_vtable); // Override the base class values. device->base.multipage = MULTIPAGE; // Set the default values. device->port = NULL; // Open the device. int rc = serial_open (&device->port, context, name); if (rc == -1) { ERROR (context, "Failed to open the serial port."); free (device); return DC_STATUS_IO; } // Set the serial communication protocol (9600 8N1). rc = serial_configure (device->port, 9600, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); if (rc == -1) { ERROR (context, "Failed to set the terminal attributes."); serial_close (device->port); free (device); return DC_STATUS_IO; } // Set the timeout for receiving data (3000 ms). if (serial_set_timeout (device->port, 3000) == -1) { ERROR (context, "Failed to set the timeout."); serial_close (device->port); free (device); return DC_STATUS_IO; } // Set the DTR and RTS lines. if (serial_set_dtr (device->port, 1) == -1 || serial_set_rts (device->port, 1) == -1) { ERROR (context, "Failed to set the DTR/RTS line."); serial_close (device->port); free (device); return DC_STATUS_IO; } // Give the interface 100 ms to settle and draw power up. serial_sleep (device->port, 100); // Make sure everything is in a sane state. serial_flush (device->port, SERIAL_QUEUE_BOTH); // Initialize the data cable (MOD mode). dc_status_t status = oceanic_vtpro_init (device); if (status != DC_STATUS_SUCCESS) { serial_close (device->port); free (device); return status; } // Switch the device from surface mode into download mode. Before sending // this command, the device needs to be in PC mode (manually activated by // the user), or already in download mode. status = oceanic_vtpro_device_version ((dc_device_t *) device, device->base.version, sizeof (device->base.version)); if (status != DC_STATUS_SUCCESS) { serial_close (device->port); free (device); return status; } // Calibrate the device. Although calibration is optional, it's highly // recommended because it reduces the transfer time considerably, even // when processing the command itself is quite slow. status = oceanic_vtpro_calibrate (device); if (status != DC_STATUS_SUCCESS) { serial_close (device->port); free (device); return status; } // Override the base class values. if (OCEANIC_COMMON_MATCH (device->base.version, oceanic_wisdom_version)) { device->base.layout = &oceanic_wisdom_layout; } else { device->base.layout = &oceanic_vtpro_layout; } *out = (dc_device_t*) device; return DC_STATUS_SUCCESS; }
static void process_outgoing (struct serial_port* port) { int avail; int r; process_type: avail = port->outgoingLen - port->outgoingSent; if ((0 == avail) && (port->outgoingPacketType == PACKET_NONE)) { return; } DBG_LOG(fprintf(debug_log_file, "process_outgoing:\n" " Buffer: len=%i sent=%i avail=%i\n" " Packet: type=%c len=%i left=%i\n", port->outgoingLen, port->outgoingSent, avail, port->outgoingPacketType, port->outgoingPacketLen, port->outgoingPacketLeft )); switch (port->outgoingPacketType) { case PACKET_NONE: /* If the number of bytes available in the buffer is at least 5, * we can begin to process this packet. We don't use avail > 5 here * because some packets may in fact have no payload, just the type. */ if (avail >= 5) { uint32_t plen; memcpy(&plen, port->outgoing + port->outgoingSent, 4); port->outgoingSent += 4; port->outgoingPacketLen = (int)(ntohl(plen) - 1); port->outgoingPacketLeft = port->outgoingPacketLen; port->outgoingPacketType = port->outgoing[port->outgoingSent++]; /* If for some reason we get a PACKET_NONE type packet, this * is an error. Switch it to PACKET_DRAIN so we can drain it * off the line. */ if (PACKET_NONE == port->outgoingPacketType) { port->outgoingPacketType = PACKET_DRAIN; } /* Loop to process the newly discovered packet type. We * may have enough data to process part of the packet by * now. */ goto process_type; } else { truncate_outgoing(port, 5); } break; case PACKET_ACTIVE: if (port->outgoingPacketLen != 1) { port->lastError.error_code = ERROR_BAD_LENGTH; serial_format_error( port->chan, port->lastError.error_code, port->lastError.error_msg, sizeof(port->lastError.error_msg)); port->outgoingPacketType = PACKET_DRAIN; goto process_type; } if (avail >= 1) { port->erlangPortActive = port->outgoing[port->outgoingSent]; port->outgoingSent++; port->outgoingPacketType = PACKET_NONE; port->outgoingPacketLen = 0; port->outgoingPacketLeft = 0; goto process_type; } else { truncate_outgoing(port, 1); } break; case PACKET_CONFIG: /* If the packet length does not exactly match the size of * the serial_cfg structure this program uses, drain the packet * off the line. There's no way it can be processed by this * code. */ if (port->outgoingPacketLen != sizeof(struct serial_cfg)) { port->lastError.error_code = ERROR_BAD_LENGTH; serial_format_error( port->chan, port->lastError.error_code, port->lastError.error_msg, sizeof(port->lastError.error_msg)); port->outgoingPacketType = PACKET_DRAIN; goto process_type; } /* If the configuration packet is fully contained within the * outgoing buffer (and it always will fit as the buffer is * always bigger), process the config packet now. */ if (avail >= sizeof(struct serial_cfg)) { struct serial_cfg cfg; char* magic = SERIAL_CFG_MAGIC; memcpy( &cfg, port->outgoing + port->outgoingSent, sizeof(struct serial_cfg)); if (memcmp(cfg.magic, magic, strlen(magic) + 1) == 0) { if (serial_configure(port->chan, &cfg) == -1) { port->lastError.error_code = serial_last_error(port->chan); serial_format_error( port->chan, port->lastError.error_code, port->lastError.error_msg, sizeof(port->lastError.error_msg)); } else { /* If the caller supplied a valid value for the active * setting, update to it. */ switch (cfg.initially_active) { case PORT_ACTIVE_FALSE: case PORT_ACTIVE_TRUE: case PORT_ACTIVE_ONCE: port->erlangPortActive = cfg.initially_active; break; } /* Modify the packet scanner to match the setting supplied. */ if (SERIAL_PACKET_NONE == cfg.packet_format) { port->packet_scanner = packetscan_none; port->incomingScan = port->incomingSent; DBG_LOG(fprintf(debug_log_file, "scanner = none\n")); } else if (SERIAL_PACKET_DELIM == cfg.packet_format) { port->packet_scanner = packetscan_delim; port->incomingScan = port->incomingSent; DBG_LOG(fprintf(debug_log_file, "scanner = delim len=%i\n", port->chan->config.packet_delim_len)); } else if (cfg.packet_format < 0) { port->packet_scanner = packetscan_fixedsize; port->incomingScan = port->incomingSent; DBG_LOG(fprintf(debug_log_file, "scanner = fixedsize %i\n", -port->chan->config.packet_format)); } port->sendOkFor = PACKET_CONFIG; } } else { /* Magic header doesn't match what we use for a * config packet. The packet is the wrong version. * This is an error. */ port->lastError.error_code = ERROR_INVALID_DATA; serial_format_error( port->chan, port->lastError.error_code, port->lastError.error_msg, sizeof(port->lastError.error_msg)); } port->outgoingSent += sizeof(struct serial_cfg); port->outgoingPacketType = PACKET_NONE; port->outgoingPacketLen = 0; port->outgoingPacketLeft = 0; goto process_type; } else { truncate_outgoing(port, sizeof(struct serial_cfg)); } break; case PACKET_CLOSE: case PACKET_FLUSH: /* If either a close or a flush messages sent sent down, send a * reply. erts is basically just waiting for the reply before * it will close the pipes down, and this process gets EOF on * the pipes. Don't attempt to close down anything until * EOF is received on the erts pipes. */ port->sendOkFor = port->outgoingPacketType; port->outgoingPacketType = PACKET_NONE; port->outgoingPacketLen = 0; port->outgoingPacketLeft = 0; goto process_type; case PACKET_DATA: /* If the buffer has more data than the packet has remaining, only * send the number of bytes in the packet. Otherwise, send what * is currently in the buffer. */ if (avail > port->outgoingPacketLeft) { r = port->outgoingPacketLeft; } else { r = avail; } /* Attempt to write to the serial port. This may fail and return -1 * (EAGAIN), meaning the port is too busy to write this data now. * A future call to this function will recall write with the same * parameter values. */ r = serial_write(port->chan, port->outgoing + port->outgoingSent, r); if (r >= 0) { port->outgoingSent += r; port->outgoingPacketLeft -= r; } else if (serial_last_error(port->chan)) { port->lastError.error_code = serial_last_error(port->chan); serial_format_error( port->chan, port->lastError.error_code, port->lastError.error_msg, sizeof(port->lastError.error_msg)); port->outgoingPacketType = PACKET_DRAIN; } /* If the packet is completed, continue to process what is in the * outgoing buffer. */ if (0 == port->outgoingPacketLeft) { port->outgoingPacketType = PACKET_NONE; port->outgoingPacketLen = 0; goto process_type; } break; case PACKET_DRAIN: default: /* If the packet type was not recognized, we need to throw the packet * away. This requires consuming all of its data, but not actually * handling it. Here we attempt to throw out as much of the packet * as we can. If we've thrown all of it, we switch back to * PACKET_NONE and try to process the buffer again. */ if (port->outgoingPacketLeft > 0) { if (avail >= port->outgoingPacketLeft) { port->outgoingSent += port->outgoingPacketLeft; port->outgoingPacketType = PACKET_NONE; port->outgoingPacketLen = 0; port->outgoingPacketLeft = 0; goto process_type; } else { port->outgoingSent += avail; port->outgoingPacketLeft -= avail; } } else if (0 == port->outgoingPacketLeft) { port->outgoingPacketType = PACKET_NONE; port->outgoingPacketLen = 0; goto process_type; } break; } }