/** Method to update the readbuf of the serial communication,
 *  as well as the connection itself.
 *  @param connection
 *    the serial struct
 *  @note
 *    the packets will be read in the following format:
 *    data\n
 *    however, the \n will be cut off
 */
static void _serial_update(serial_t *connection) {
  int numAvailable;
  int totalBytes;

  /* dynamically reconnect the device */
  if (access(connection->port, F_OK) == -1) {
    if (connection->connected) {
      connection->connected = 0;
      connection->fd = -1;
    }
  } else {
    if (!connection->connected) {
      if ((connection->fd = open(connection->port, O_RDWR | O_NOCTTY | O_NDELAY)) != -1) {
        if (_serial_setattr(connection) == 0) {
          connection->connected = 1;
        } else {
          close(connection->fd);
          connection->fd = -1;
        }
      }
    }
  }
  if (!connection->connected)
    return;

  /* update buffer */
  if ((numAvailable = read(connection->fd, tempbuf, SWREADMAX)) > 0) {
    char *start_index, *end_index;
    tempbuf[numAvailable] = '\0';
    if ((totalBytes = strlen(connection->buffer) + numAvailable) >= SWBUFMAX) {
      totalBytes -= SWREADMAX;
      memmove(connection->buffer, &connection->buffer[totalBytes],
          (SWBUFMAX - totalBytes) * sizeof(char));
      connection->buffer[SWBUFMAX - totalBytes] = '\0';
    }
    strcat(connection->buffer, tempbuf);

    if ((end_index = strrchr(connection->buffer, '\n'))) {
      end_index[0] = '\0';
      end_index = &end_index[1];
      start_index = strrchr(connection->buffer, '\n');
      start_index = start_index ? &start_index[1] : connection->buffer;
      memcpy(connection->readbuf, start_index,
          (strlen(start_index) + 1) * sizeof(char));
      memmove(connection->buffer, end_index,
          (strlen(end_index) + 1) * sizeof(char));
      connection->readAvailable = 1;
    }
  }
}
示例#2
0
文件: serial.c 项目: ajay/ROSE
/** Connect to a serial device.
 *  @param connection
 *    a pointer to the serial struct
 *  @param port
 *    a portname; if NULL, will open a random port
 *  @param baudrate
 *    the bits per second of information to transmit/receive
 *  @return 0 on success, -1 on failure
 */
int serial_connect(serial_t *connection, char *port, int baudrate)
{
	connection->connected = 0;
	if (port)
	{
		connection->port = (char *)malloc((strlen(port) + 1) * sizeof(char));
		strcpy(connection->port, port);

		if ((connection->fd = open(connection->port, O_RDWR)) == -1)
		{
			goto error;
		}
	}
	else
	{
		DIR *dp;
		struct dirent *ent;
		char hasPossibleSerial;

		if (!(dp = opendir(INPUT_DIR)))
		{
			fprintf(stderr, "Cannot find directory %s to open serial connection\n", INPUT_DIR);
			return -1;
		}

		while ((ent = readdir(dp)))
		{
			const char *prefix;
			int i;
			hasPossibleSerial = 0;
			for (prefix = PREFIXES[(i = 0)]; prefix != NULL; prefix = PREFIXES[++i])
			{
				if (strstr(ent->d_name, prefix))
				{
					connection->port = (char *)malloc((strlen(INPUT_DIR) + strlen(ent->d_name) + 1) * sizeof(char));
					sprintf(connection->port, "%s%s", INPUT_DIR, ent->d_name);

					if ((connection->fd = open(connection->port, O_RDWR | O_NOCTTY | O_NONBLOCK)) == -1)
					{
						free(connection->port);
						connection->port = NULL;
					}
					else
					{
						hasPossibleSerial = 1;
						break;
					}
				}
			}

			if (hasPossibleSerial)
			{
				break;
			}
		}

		if (!hasPossibleSerial)
		{
			fprintf(stderr, "Cannot find a serial device to open\n");
			return -1;
		}
	}

	/* set connection attributes */
	connection->baudrate = baudrate;
	connection->parity = 0;

	if (_serial_setattr(connection) == -1)
	{
		goto error; /* possible bad behavior */
	}

	tcflush(connection->fd, TCIFLUSH);
	tcflush(connection->fd, TCOFLUSH);
	connection->connected = 1;
	memset(connection->buffer, 0, SWBUFMAX);
	memset(connection->readbuf, 0, SWREADMAX);
	connection->readAvailable = 0;
	printf("Connected to %s\n", connection->port);
	return 0;

	error:
		fprintf(stderr, "Cannot connect to the device on %s\n", connection->port);
		connection->connected = 0;

		if (connection->fd != -1)
		{
			close(connection->fd);
		}
		connection->fd = -1;

		if (connection->port)
		{
			free(connection->port);
		}

		connection->port = NULL;
		return -1;
}
示例#3
0
文件: serial.c 项目: ajay/ROSE
/** Method to update the readbuf of the serial communication,
 *  as well as the connection itself.
 *  @param connection
 *    the serial struct
 *  @note
 *    the packets will be read in the following format:
 *    data\n
 */
static void _serial_update(serial_t *connection)
{
	int bytesRead;
	int bytesStored;
	unsigned char analyzeBuffer;

	/* dynamically reconnect the device */
	if (access(connection->port, F_OK) == -1)
	{
		if (connection->connected)
		{
			connection->connected = 0;
			connection->fd = -1;
		}
	}

	else
	{
		if (!connection->connected)
		{
			if ((connection->fd = open(connection->port, O_RDWR | O_NOCTTY | O_NDELAY)) != -1)
			{
				if (_serial_setattr(connection) == 0)
				{
					connection->connected = 1;
				}
				else
				{
					close(connection->fd);
					connection->fd = -1;
				}
			}
		}
	}

	if (!connection->connected)
	{
		return;
	}

	/* update buffer constantly (be careful of overflow!) */
	analyzeBuffer = 0;
	while ((bytesRead = read(connection->fd, tempbuf, SWREADMAX)) > 0)
	{
		if (bytesRead > 0)
		{
			analyzeBuffer = 1; /* turn on buffer analysis signal */
		}
		tempbuf[bytesRead] = '\0';
		bytesStored = strlen(connection->buffer); /* no \0 */

		while (bytesStored + bytesRead >= SWBUFMAX)
		{
			/* shorten it by only half of the readmax value */
			bytesStored -= SWREADMAX / 2;
			memmove(connection->buffer, &connection->buffer[SWREADMAX / 2], (bytesStored + 1) * sizeof(char));
		}

		strcat(connection->buffer, tempbuf);
	}

	if (analyzeBuffer)
	{
		char *start_index, *end_index;
		size_t nbytes;
		if ((end_index = strrchr(connection->buffer, '\n')))
		{
			end_index[0] = '\0';
			end_index = &end_index[1];
			start_index = strrchr(connection->buffer, '\n');
			start_index = start_index ? &start_index[1] : connection->buffer;
			nbytes = (size_t)end_index - (size_t)start_index;
			memcpy(connection->readbuf, start_index, nbytes * sizeof(char));
			connection->readbuf[nbytes + 1] = '\n'; /* put the \n back */
			connection->readbuf[nbytes + 2] = '\0';
			memmove(connection->buffer, end_index, (strlen(end_index) + 1) * sizeof(char));
			connection->readAvailable = 1;
		}
	}
}