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;
}
示例#4
0
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;
}
示例#5
0
/** 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);
            }
        }
    }
}
示例#6
0
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;
    }
}