예제 #1
0
파일: serial.c 프로젝트: sdelgran/GIMX
int read_packet(int id)
{
  int ret = read_header(id);
  
  /*
   * Since we are reading with no timeout,
   * a positive value indicates that the header is complete.
   */
  if(ret > 0)
  {
    ret = read_value(id);

    /*
     * Since we are reading with no timeout,
     * a non-negative value indicates that the value is complete.
     */
    if(ret >= 0)
    {
      ret = adapter_process_packet(id, serials[id].data);

      serials[id].bread = 0;
    }
  }
  
  return ret;
}
예제 #2
0
파일: serial.c 프로젝트: code4bones/GIMX
/*
 * \brief This function tries to read 'size' bytes of data.
 *
 * It blocks until 'size' bytes of data have been read or after 1s has elapsed.
 * It should only be used in the initialization stages, i.e. before the mainloop.
 *
 * \param id     the instance id
 * \param pdata  the pointer where to store the data
 * \param size   the number of bytes to retrieve
 *
 * \return the number of bytes actually read
 */
int serial_recv(int id, void* pdata, unsigned int size)
{
  int bread = 0;
  int res;

  fd_set readfds;

  struct timeval timeout = {.tv_sec = 1, .tv_usec = 0};

  while(bread != size)
  {
    FD_ZERO(&readfds);
    FD_SET(serials[id].fd, &readfds);
    int status = select(serials[id].fd+1, &readfds, NULL, NULL, &timeout);
    if(status > 0)
    {
      if(FD_ISSET(serials[id].fd, &readfds))
      {
        res = read(serials[id].fd, pdata, size-bread);
        if(res > 0)
        {
          bread += res;
        }
      }
    }
    else if(status == EINTR)
    {
      continue;
    }
    else
    {
      break;
    }
  }

  return bread;
}

/*
 * \brief This function closes a serial port.
 *
 * \param id  the instance id
 *
 * \return 0
 */
int serial_close(int id)
{
  if(serials[id].fd >= 0)
  {
    usleep(10000);//sleep 10ms to leave enough time for the last packet to be sent
    close(serials[id].fd);
    serials[id].fd = -1;
  }
  return 0;
}

/*
 * \brief the serial callback for serial ports that are added as event sources.
 *
 * \param id  the instance id
 *
 * \return 0 in case of a success, -1 in case of an error
 */
static int serial_callback(int id)
{
  int nread;
  int ret = 0;
  
  unsigned char* base = (unsigned char*)&serials[id].packet;

  if(serials[id].bread < HEADER_SIZE)
  {
    /*
     * read the first two bytes first so as to retrieve the data length
     */
    nread = read(serials[id].fd, base+serials[id].bread, HEADER_SIZE-serials[id].bread);

    if(nread >= 0)
    {
      serials[id].bread += nread;
    }
    else
    {
      fprintf(stderr, "%s:%d read: %m", __FILE__, __LINE__);
      ret = -1;
    }
  }
  else
  {
    /*
     * read the data
     */
    nread = read(serials[id].fd, base+serials[id].bread, serials[id].packet.header.length-(serials[id].bread-HEADER_SIZE));

    if(nread >= 0)
    {
      serials[id].bread += nread;

      if(serials[id].packet.header.length + HEADER_SIZE == serials[id].bread)
      {
        ret = adapter_process_packet(id, &serials[id].packet);

        serials[id].bread = 0;
      }
    }
    else
    {
      fprintf(stderr, "%s:%d read: %m", __FILE__, __LINE__);
      ret = -1;
    }
  }

  return ret;
}