int Serial::readUntil(const char *aUntil, char *aBuffer, int aLength) { if (!mConnected) { gLogger->error("Trying to read when not connected"); return -1; } gLogger->debug("Reading upto %d bytes or '%c' we get a match", aLength, aUntil); int len = 0, count = 0; char *cp = aBuffer; const char *match = aUntil; do { int ret = read(cp, 1); if (ret == -1) { throw SerialError("Couldn't read"); } if (ret == 0) { usleep(10 * 1000); // 10 msec if (count++ > 10) { gLogger->info("Read timed out\n"); return -1; } } else { count = 0; //printf("Received: %d == match: %d\n", *cp, *match); if (*match == *cp) match++; else match = aUntil; // See if we can match the beginnig of the string again. if (*match == *cp) match++; //printf("Match now: %d\n", *match); cp++; len++; } } while (len <= aLength && *match != '\0'); *cp = '\0'; gLogger->debug("Read returned: %d - '%s'", len, aBuffer); return len; }
int Serial::write(const char *aBuffer) { gLogger->debug("Writing '%s'\n", aBuffer); int ret = write(aBuffer, (int) strlen(aBuffer)); if (ret < 0) throw SerialError("Couldn't write"); gLogger->debug("Write returned: %d\n", ret); return ret; }
bool Serial::flushInput() { char buffer[2]; int ret; do { ret = read(buffer, 1); if (ret < 0) throw SerialError("Couldn't read"); } while (ret > 0); #ifdef WIN32 DWORD errors; COMSTAT stat; ClearCommError(mFd, &errors, &stat); #else tcflush(mFd, TCIFLUSH); #endif return true; }
void Serial::init() { if (this->isConnected) port->close(); port = new QextSerialPort(this->portStr); //we create the port connect(port, SIGNAL(readyRead()), this, SLOT(onDataAvailable())); port->open(QIODevice::ReadWrite | QIODevice::Unbuffered); //we open the port if(!port->isOpen()) throw SerialError("Unable to open the port!"); //we set the port properties port->setBaudRate(BAUD9600);//modify the port settings on your own port->setFlowControl(FLOW_OFF); port->setParity(PAR_NONE); port->setDataBits(DATA_8); port->setStopBits(STOP_1); this->isConnected = true; }
/** Processes a character from a serial stream * and reconstructs packets. * @param data The next character in the stream */ void ProcessDataChar (SerialData * s, byte data) { /* Unstuff bytes and locate start bytes here */ /* See if the data received is value to ignore * This most likely occurs in conjunction with * a frame error: start byte detected, but no * valid data afterwards. */ if (data == NULL_BYTE || data == MAX_BYTE) { SerialError(s, ERR_RECEIVED_IGNORE_BYTE); return; } /* If any start byte is found, any current data * transfer will be reset, and a new data transfer * will begin. */ if (data == START_BYTE) /* Start byte */ { if (s->receive_state != PROC_STATE_AWAITING_START_BYTE) { SerialError(s, ERR_START_BYTE_INSIDE_PACKET); } /* Reset state */ s->receive_state = PROC_STATE_AWAITING_ADDRESS; s->receive_data_count = 0; s->receive_next_char_is_escaped = false; } else { if (s->receive_state == PROC_STATE_AWAITING_START_BYTE) { SerialError(s, ERR_UNEXPECTED_START_BYTE); //printf("Unexpected Start Byte: Expected 0x%x, Got 0x%x\n", START_BYTE, data); } else { /* Otherwise, unstuff bytes and send data to the state machine */ if (data == ESCAPE_CHAR) // Escape Character { s->receive_next_char_is_escaped = true; } else { if (s->receive_next_char_is_escaped) { s->receive_next_char_is_escaped = false; switch (data) { case ESCAPE_CHAR_ESCAPED: data = ESCAPE_CHAR; break; case START_BYTE_ESCAPED: data = START_BYTE; break; case NULL_BYTE_ESCAPED: data = NULL_BYTE; break; case MAX_BYTE_ESCAPED: data = MAX_BYTE; break; } } SerialStateMachineProcess(s, data); } } } }
void SerialStateMachineProcess(SerialData *s, byte data) { switch (s->receive_state) { case PROC_STATE_AWAITING_ADDRESS: s->receive_address = data; s->receive_checksum = data; s->receive_state = PROC_STATE_AWAITING_LENGTH; break; case PROC_STATE_AWAITING_LENGTH: if (data > SERIAL_RECEIVE_BUFFER_SIZE) { /* Error, length too long. Ignore packet. */ s->receive_state = PROC_STATE_AWAITING_START_BYTE; /* Look for the next start byte. Note: this * will likey produce unexpected start byte errors. */ SerialError(s, ERR_EXCESSIVE_PACKET_LENGTH); } else { s->receive_length = data; s->receive_checksum += data; s->receive_state = PROC_STATE_AWAITING_DATA; } break; case PROC_STATE_AWAITING_DATA: s->receive_length--; s->receive_checksum += data; s->receive_data[s->receive_data_count] = data; s->receive_data_count++; if (s->receive_length == 0) { s->receive_state = PROC_STATE_AWAITING_CHECKSUM; } break; case PROC_STATE_AWAITING_CHECKSUM: s->receive_checksum = ~s->receive_checksum; if (data == s->receive_checksum) { if (s->ReceivePacketComplete != NULL) { s->ReceivePacketComplete (s); } } else { SerialError(s, ERR_CHECKSUM_MISMATCH); //printf("Error: Checksum Mismatch. Expected 0x%x, Got 0x%x\n", s->receive_checksum, data); } s->receive_state = PROC_STATE_AWAITING_START_BYTE; break; default: // (It'll never get here) break; } }